TOPIC 5|GISで活用する[2/3]|QGISのGRASSプラグインを使って都市陰影図を作る
QGISでは、QGIS本体、もしくは、さまざまなプラグインを使って分析や解析ができます。「GRASSプラグイン」を使って、建物の高さだけ地形を盛り上げ、ある日時において影になる部分を示す、都市陰影図を作る方法を紹介します。

【目次】
5.2.7 GRASSプラグインを使って都市陰影図を作る
5.2.7 _ GRASSプラグインを使って都市陰影図を作る
QGISでは、QGIS本体、もしくは、さまざまなプラグインを使って分析や解析ができます。
ここでは、ラスター演算を中心とした豊富な関数群を使って地形解析の機能を持つ「GRASS」というGISと連携する「GRASSプラグイン」を使って、建物の高さだけ地形を盛り上げ、ある日時において影になる部分を示す、都市陰影図を作る方法を紹介します(図 5-28)。
【メモ】
QGISのバージョンによっては、GRASSが備える一部の機能でエラーが発生することがあります。その場合は、以前のバージョンで試してみてください。本稿は、QGIS 3.26.3(with GRASS 7.8.7)で動作確認しています。

コラム:GRASSについて
GRASSは、古くからあるオープンソースGISソフトウェアです。主にコマンドライン操作で、さまざまな処理をするものですが、GRASSプラグインを用いることで、QGISの機能と組み合わせて使うことができます。
QGISには、コアプラグインとして「GRASS GIS provider」と「GRASS 7」が含まれています。前者はデータの管理と可視化をするプラグインで、後者は分析をするプラグインです。
■ GRASSプラグインとProcessingプラグインの有効化
GRASSプラグインは、QGISのコアプラグインなので既定でインストールされています。しかし、有効化はされていません。
またのちの手順では、ジオメトリを加工するために、各種ジオメトリの計算や統合などの計算ができるProcessingプラグインも利用します。ここでは、次の手順で、2つとも有効化しておきます。
[1]プラグイン管理画面を開く
[プラグイン]メニューから[プラグインの管理とインストール]を選択します(図 5-29)。

[2]GRASSプラグインを有効化する
[インストール済み]タブをクリックし、[GRASS 7]と[Processing]にチェックを付けます。[閉じる]をクリックして、この画面を閉じます(図 5-30)。

[3][プラグイン]メニューに[GRASS]が追加される
[プラグイン]メニューに[GRASS]が追加されたことを確認します(図 5-31)。

■ DEMデータで高さを表現する
GISでは、高さの凹凸を示す地理空間情報があるとき、そのうえに、ラスターレイヤーを、あたかも布をかけたかのようにして、その凹凸を反映させる「ドレープ処理」という機能があります。この方法を使って、地図や航空写真などに凸凹を付けると、実際の高低差を表現できます(図 5-32)。

凸凹のデータを表現するには、いくつかの方法がありますが、よく使われるのは「DEM(Digital Elevation Model、数値標高モデル)」と呼ばれる形式です。これは、グリッド状に区切って高さを付与したデータです。
今回は、このDEM形式のデータの高さ情報を色の濃淡に変換した、GeoTIFF形式のラスター画像を使います(図 5-33)。GeoTIFFは、ビットマップ(ラスター)形式の画像ファイルであるTIFF形式ファイルを拡張したもので、メタデータとして緯度経度の情報を付与したものです。

一般に、ドレープ処理は、地形の起伏を航空写真などに適用して地面の凹凸を反映するときに使いますが、今回は、建物の高さを適用することで地面を盛り上げて高さを表現し、そこに、太陽の位置や時間によって陰影図を作成するツールを用いて、日の当たり具合を可視化します。
■ QGISとGRASSとの関係
以下の操作では、QGISとGRASSを組み合わせて利用していきます。GRASSは、QGISと一体化して動きますが、プラグインを経由して用いる、異なるツールです。
QGISのレイヤを、そのまま利用することはできず、いったんGRASSの「マップセット」と呼ばれるデータベースに取り込んで処理し、その処理結果をQGISに、再びレイヤとして適用するという流れをとります。GRASSからQGISのデータを参照することはできないので注意してください(図 5-34)。

以降の操作では、処理した結果を、「シェープファイル形式」と呼ばれるファイルに保存する場面があります。一見、無駄にも見えますが、マップセットに置いたままでは、QGISで参照できない場面があるためです。ファイルへの保存を省略すると、エラーが発生したり、うまく変換できなかったりすることがあるので注意してください。
【メモ】
シェープファイル(Shapefile)は、GIS業界でよく使われるArcGIS(後述)を開発したEsri社が提唱するベクター形式のフォーマットで、さまざまなGISソフトウェアにおいて採用されている一般的なフォーマットです。
シェープファイルを使う場合は、次の点に注意してください。
・ファイル名には、日本語などのマルチバイト文字はなるべく使わないようにしてください。
・属性データの文字エンコードは、dbase ファイルのLDID(Language driver ID)で指定することになっていますが、シェープファイルを作成したソフトウェアやそのときのバージョンにより、正しく指定されているかはまちまちです。現在、多くのソフトウェアではUTF-8でシェープファイルを作成することが多いですが、新規作成する場合は、エンコードに注意してください。
・シェープファイルは複数ファイルで構成されるフォーマットです。エクスプローラなどで別の場所にコピーするには、必要なファイル全部をコピーするようにしてください。
■ 処理の流れ
以下では、次の操作で、建物の陰影図を作ります(図 5-35)。

① GRASSへのインポート
まずは、建物のCityGMLファイルをQGISのレイヤとして読み込みます。それをいったん、シェープファイル形式に書き出し、それからGRASSにインポートします。「v.in.ogr」のように図中で書いているのは、GRASSのモジュール名です。すぐあとに説明しますが、GRASSには、さまざまなモジュールがあり、それを組み合わせて、処理していきます。
② 高低を示すGeoTIFFの作成
建物のCityGMLも、それを取り込んだ①の状態でも、これはベクターデータです。これをラスター形式に変換し、高低を示すGeoTIFF画像を作ります。
CityGMLで提供されている建物のデータには、その高さが「measuredHeight」という属性に格納されているので、その情報を使います。
③ 陰影図を作る
GRASSに含まれているr.sunmask.date.timeというモジュールを使って、②のファイルから陰影図を作ります。
④ 3D表示する
②と③を重ね合わせて3Dで表示します。3D表示するには、Qgis2threejsというプラグインを使います。
Qgis2threejsでは、マップセットのなかにあるデータは処理できないので、一度、シェープファイル形式として書き出し、それをレイヤに表示している点に注意してください。QGISでは、マップセットのデータをそのまま表示できるものの、これは表示するだけの機能なので、Qgis2threejsからの操作には失敗します。
【メモ】
3D表示に「5.2.6 3Dビューで表示する」で説明した3Dビューではなく、Qgis2threejsを使っているのは、2つのレイヤを重ねて3D表示したいからです。
■ 建物のデータを読み込む
では、これらの一連の操作をしていきます。
以下では、いったんこれまでの作業は保存する、もしくは破棄し、改めて[プロジェクト]メニューから[新規]を作成して、新規プロジェクトとして始めます(図 5-36)。

まずは、CityGMLで提供されている建築物モデルのデータをQGISに読み込みます。
[1]ベクタレイヤを追加する
[レイヤ]―[レイヤを追加]―[ベクタレイヤを追加]を選択します。
[2]建築物モデルのデータを読み込む
ベクタのデータセットとして、建築物モデルのデータを読み込みます。ここでは先ほど利用したのと同じ、建物の3次メッシュコード「53394631」(御茶ノ水・神田・秋葉原のエリア)のudx/bldg/53394631_bldg_6697_2_op.gmlを開きます。

[3]アイテムを選択する
図 5-37において[追加]ボタンをクリックします。すると、どのアイテムを追加するのか選択する画面が表示されます。デフォルトでは、すべて選択状態になっているので、そのまま[レイヤを追加]をクリックします。
追加したら、先ほどの図 5-37は[閉じる]ボタンをクリックして閉じます。

■ ジオメトリを修復してシェープファイルに書き出す
こうして読み込んだレイヤを、後続の操作においてGRASSで扱うため、一度シェープファイル形式に変換します。
シェープファイルに変換するには、レイヤを右クリックして、[エクスポート]―[新規ファイルに地物を保存]から行うのが基本です(図 5-39)。

しかしこの方法では、不正なポリゴンがあると削除されてしまうため、ジオメトリの修復をして書き出すことを推奨します。ジオメトリの修復は、ツールボックスにあります。次のように操作します。
[1]ツールボックスを開く
[プロセシング]メニューの[ツールボックス]を選択して、ツールボックスを開きます。
【メモ】
[プロセシング]メニューが表示されていないときは、Processingプラグインが有効でない可能性があります。

[2]ジオメトリの修復を開く
プロセシングツールボックスが開いたら、[ベクタジオメトリ]の配下の[ジオメトリを修復]をダブルクリックして起動します(図 5-41)。

[3]ジオメトリの修復をしてファイルに書き出す
すると、入力レイヤと出力レイヤの選択画面が表示されます。いまは建物を取り込んだレイヤしかないので、それが入力レイヤとして選択されているはずです。
出力レイヤは[一時レイヤを作成]となっており、実行すれば、結果が別のレイヤとして作成されます。ここでは、シェープファイル形式に変換したいので、その右のボタンから[ファイルに保存]を選択します。するとファイル名と保存先を尋ねるダイアログボックスが表示されるので、[SHP files(*shp)]を選択して、適切なファイル名を入力します。ここでは、kanda.shpとしました。
ファイル名自身、そして保存先のフォルダ名には、日本語を含まないようにしてください。そうしないと、のちの操作でGRASSにインポートするときに失敗します。
ファイルを選択したら、ひとつ前の画面に戻るので、[実行]をクリックします。
【メモ】
今回利用しているデータは、ポリゴン数がさほど多くないので、1分もあれば終わりますが、ポリゴン数が多い場合、完了には、数時間かかることもあります(例えば、地形のデータ(PLATEAUの3D都市モデルのudex/demフォルダに含まれているもの)は、実際、変換に相当な時間がかかります)。


[4]新しいレイヤが重なった
シェープファイル形式に変換され、新しいレイヤとして登録されました。変換前のもとのCityGMLのレイヤは、もう必要ないので、右クリックして[レイヤを削除]を選択し、削除しておきます(図 5-44)。

■ マップセットの作成
これでGRASSに読み込むシェープファイル形式のデータを準備できました。次に、GRASSの操作に入っていきます。
GRASSは、QGISとは別のソフトウェアです。先にも説明しましたが、GRASSのなかでは、地図データを「マップセット」と呼ばれる概念で扱います。そこでまずは、マップセットを作成します。
[1]対象の場所全体を表示しておく
以下の操作を読むとわかりますが、マップセットを作るときは、対象とする領域を、GRASSの作業領域として定義します。その定義において、緯度経度を手入力するのは複雑なので、以下の手順では、「現在QGISで表示している範囲」を自動で設定することにします。
そのための準備として、レイヤを右クリックして[レイヤ領域にズーム]を選択し、含まれる地物全体をQGISで表示するようにしておきます(図 5-45)。

[2]新規マップセットの作成
[プラグイン]メニューから[GRASS]―[新規Mapset]を選択して、新規マップセットを作成します(図 5-46)。

[3]データベースディレクトリの設定
マップセットは、特定のフォルダの下にまとめて保存されます。その保存先のことを「データベースディレクトリ」と言います。デフォルトでは、grassdataフォルダが指定されています。通常は、そのままでかまいません(図 5-47)。

[4]ロケーションを作成する
データベースディレクトリのなかに、プロジェクトごとにロケーションと呼ばれる場所を作って、そこにデータを保存して管理します。ここでは[新規ロケーションを作成]を選択して、適当なロケーション名を入力します。ここでは「Kanda」としておきます。

[5]投影法の選択
投影法を選択します。ここでは、PLATEAUで採用されている投影法の6697を選択します。

[6]GRASS領域の設定
GRASSが扱うラスターモジュールのワークスペースの範囲を定義します。デフォルトでは、世界全体が設定されていますが、これだとうまくいかないので、分析の範囲だけを設定するようにします。
ここまでの流れでは、QGIS上で、建築物モデルを読み込んだレイヤ全体が表示されるようにしました(前掲の図 5-45における操作)。そこで[現在のQGISの範囲を設定]ボタンをクリックします。すると、東西南北の設定が、現在QGISで表示している範囲に設定されます。設定したら、[次へ]をクリックします(図 5-50)。

[7]マップセットの定義
最後にマップセットを定義します。マップセットは、分析対象ごとに用意する作業領域です。ここでは「citygml」としておきます(図 5-51)。

[8]確認
確認画面が表示されます。[完了]をクリックします(図 5-52)。

マップセットを作成すると、GRASS領域として指定した部分が赤枠で表示されますが、それ以外の大きな変化はありません。[ブラウザ]パネルから[ホーム]以下を確認すると、フォルダとして存在することがわかります。
【メモ】
どのフォルダに作成されるのかは、データベースディレクトリとして何を設定したかによります(図 5-46を参照)

■ GRASSに取り込む
これでGRASSを使う準備ができました。次に、先ほどシェープファイル形式に変換した建物データを、GRASSに取り込みます。
[1]GRASSツールを開く
[プラグイン]メニューから[GRASS]―[GRASSツールを開く]を選択して、GRASSツールを開きます(図 5-54)。

[2]インポートツールを選ぶ
画面右にGRASSツールが表示されます。さまざまツールが階層で分類されて格納されています。これらのツールには名前が付いていて、[フィルタ]の部分で何文字か入力すると、その名前に合致するものだけに絞り込まれます。
先ほど作成したシェープファイル形式からマップセットに読み込むには、「v.in.ogr」というツールを使います。フィルタに、その何文字かを入力して絞り込み、このツールをクリックします(図 5-55)。
【メモ】
v.in.ogrの代わりにv.in.ogr.qgisを使って、いまQGISで開いているレイヤを読み込むこともできます。

[3]ベクトルマップに変換する
v.in.ogrが開きます。[Name of OGR datasource to be imported]の部分で、インポート元となるシェープファイル(先ほど保存したkanda.shpファイル)を選択します。
[出力するベクトルのマップ名]の部分に、マップセットにインポートする任意の名前を入力します。英語の大文字や日本語を使うと失敗するので、「小文字の英数字」のみの名前を付けてください。ここでは「kanda_bld」とし、[実行]ボタンをクリックします(図 5-56)。
すると変換が始まります。処理の完了までには、数分かかることがあります。

コラム:「完了しましたがエラーがあります」と表示されたときは
変換したときに「完了しましたがエラーがあります」と表示されたときは、[Name of OGR datasoucre to be imported]で、日本語を含むフォルダ・ファイル名を指定している可能性があります。英語のみのフォルダに移動して、再度、試してみてください。

[4]出力を見る
処理が完了したら[出力を見る]をクリックします。すると、QGISのレイヤとして登録されます(図 5-58)。
見た目は、まったく同じものが重なっていますが、ひとつはQGIS管理下のレイヤ、もうひとつはGRASS管理下のレイヤです。QGIS管理下のレイヤは、以降の作業では必要ないので、削除しておきます(図 5-59)。
なお、変換後はピッタリ重なるはずですが、図 5-58を見るとわかるように、少し抜けた部分があります。これはインポートする際に、不正なポリゴンがあって除外されたところです。


コラム:出力を見る前に閉じてしまったときは
[出力を見る]ボタンをクリックする前に、GRASSツールを閉じてしまったときは、左側のブラウザのツリーから、該当のマップをドラッグ&ドロップして登録してください。

■ ラスター化する
これで、GRASSでデータを扱えるようになりました。いま登録されているのは、ベクターデータです。このデータを、高さを色の濃淡で示すラスターデータに変換します。
[1]v.to.rast.attrを選択する
属性値を元にラスターデータに変換するツールが、v.to.rast.attrです。GRASSツールからクリックして開きます。

[2]入力ベクトルマップと高さに使う属性を選ぶ
v.to.rast.attrでは、次の3つの値を入力します。
・入力するベクトルマップ名
入力するベクトルマップの名前です。先ほど作成したkanda_bldを選択します。
・Attribute field
高さとして利用する属性です。ここでは「mesuredHeight」を選択します(選択肢には、mesuredHeまでしか表示されません)。
・出力ラスターマップ名
変換後のマップに付ける名前を指定します。ここでは「kanda_ras」としておきます。
すべて入力したら[実行]をクリックして実行します。実行が終わったら、[出力を見る]をクリックして、結果をQGISのレイヤとして登録します。


[3]高さが濃淡で示された
高さが濃淡で示されたレイヤが追加されました。

[4]GeoTIFF形式として保存する
このレイヤは、マップセットを表示しているものです。このままだとあとで、Qgis2threejsで参照するときに見えないので、エクスポートしておきます。エクスポートするには、レイヤ名を右クリックして、[エクスポート]―[名前を付けて保存]を選択します(図 5-65)。
ファイル形式は、ここでは「GeoTIFF」としておきます。GeoTIFFは、TIFF形式の画像に緯度経度の情報を付けたもので、GISにおいてラスター形式を保存する際に、一般的に使われる形式です。ファイル名は任意でかまいませんが、「kandaras」とでもしておきます。保存時の座標参照系(CRS)は、ESPG:6697を選択します。


■ 陰影図を作る
この濃淡データを使って、陰影図を作ります。GRASSには、次の2つの陰影図ツールがあります。
・r.sunmask.position
太陽の位置によって陰影図を作ります。
・r.sunmask.date.time
日時を指定して陰影図を作ります。
ここでは、r.sunmask.date.timeを使って、2022年1月1日の陰影図を作ってみます。
[1]r.sunmask.date.timeを起動する
GRASSツールから、r.sunmask.date.timeをクリックして起動します。

[2]ラスターマップや年月日を指定する
[Name of input elevation raster map]の部分で、高さが濃度として表現されたラスターマップを選択します。ここではkanda_rasを選択します。
そして、Year~Secondsに、日時を設定します。ここでは、2022年1月1日の12:00:00のマップを作ってみます。Timezoneには、日本のタイムゾーンである「9」を設定します。
[出力ラスターマップ名]には、生成物を保存するマップ名を指定します。ここでは「sun_20220101_120000」としておきます。
上記項目を入力したら、[実行]ボタンをクリックします。この処理には、しばらく時間がかかります(実行環境次第ですが、数時間かかるケースもあります)。
実行が完了したら、[出力を見る]をクリックして、QGISのレイヤとして追加します。


[3]陰影図を確認する
陰影図のレイヤだけにチェックを付けて、確認します。光っているところが、日が当たっているところです。南方向から光が当たっているようです。

[4]GeoTIFF形式ファイルとしてエクスポートする
Qgis2threejsで参照できるようにするため、こうして追加したレイヤをエクスポートしてGeoTIFF形式として保存しておきます。ファイル名は任意でかまいませんが、「sunset.tif」としておきます。保存時の座標参照系(CRS)は、ESPG:6697を選択します。
■ Qgis2threejsで3D表示する
この表示ではわかりにくいので、3D表示してみましょう。3D表示するには、Qgis2threejsプラグインを使います。
・Qgis2theejsのインストール
まずは、Qgist2threejsをインストールします。
[1]プラグインの管理とインストールを開く
[プラグイン]メニューから[プラグインの管理とインストール]を選択します。

[2]Qgis2threejsをインストールする
[未インストール]をクリックし、「Qgis2threejs」を探してクリックします。[インストール]をクリックしてインストールします。

・3D表示する
Qgis2threejsプラグインは、3Dマップビューと同様、投影座標系でしか利用できないので、右下の現在のEPSGが表示されている部分をクリックして、切り替えます。ここでは、「平面直角座標の9系(EPSG:6677)」に切り替えます(図5-73)。
Qgis2threejsプラグインを追加すると、[Web]メニューが追加されます。ここからQgis2threejsを起動します。ここではプレビュー機能がある[Qgis2threejs Exporter]を選択します。
【メモ】
with Preview Offのほうは、プレビューすると処理が遅い場合など、プレビューなしで操作したいときに使います。

すると、プレビュー画面が表示されます。左側の[Layers]の部分で、何を表示するのかを選択します。エクスポートしている[sunset]と[kandaras]にチェックを付けると、日の当たり具合がわかります(図 5-74)。
【メモ】
sunsetやkandarasが表示されていない場合、ファイルをエクスポートしていない可能性があります。

コラム:PLATEAUに含まれる地形(起伏)情報
ここでは建物の高さの分だけ持ち上げることで、日の当たり具合を確認しましたが、よく使われるのは、地形の起伏を適用することで、実際の地図に凹凸を付けるやり方です。
PLATEAUの3D都市モデルのudx/demフォルダには、地形の起伏データが含まれており、ここで説明したやり方を適用すれば、実際に地図に凹凸を付けられます。
しかしudx/demフォルダに格納されている地形データは容量が大きく、処理にとても時間がかかります。そこで代わりの方法として、国土地理院が「基盤地図情報ダウンロードサービス」(https://fgd.gsi.go.jp/download/menu.php)で提供しているDEMを使う方法も、よく使われています。
株式会社MIERUNEが作成しているQuickDEM4JPというプラグインを使うと、国土地理院で提供されているGML形式のファイルを読み込んで、GeoTIFF形式やTerrian RGB形式に変換できます。やり方については、MIERUNEのブログに記載されています。
【QuickDEM4JP】
https://plugins.qgis.org/plugins/QuickDEM4JP/
【QuickDEM4JPの使い方】
https://qiita.com/nokonoko_1203/items/b99aa733cb215305f8aa
【文】
大澤文孝
【監修】
於保俊(株式会社ホロラボ)
西尾悟(株式会社MIERUNE)
曲新苗(株式会社MIERUNE)
飯田知靖(朝日航洋株式会社)
ESRIジャパン株式会社