3D都市モデルから高さの情報を処理していた話 (3D都市モデル Project PLATEAU Advent Calendar 2023)
本記事は 3D都市モデル Project PLATEAU Advent Calendar 2023 の21日目の記事です。
今年仕事で使う機会があって入門したPlateau初心者です。枠が空いてたので書きました。
背景
あるとき、Google Street Viewと同じ景色を、Plateauのモデルが整備されている地域で再現できないか?ということを検討していました。
やりたいことのイメージ図は、こういう感じです。
ストリートビューの風景 | 3Dモデルの風景 (目標) |
---|---|
やったことの紹介
BlenderかUEを使うと良いのですが、僕自身はBlenderの世界にPlateauモデルを置いて遊ぶことが多かったです (手元のPCで動くのがBlenderだった…)。
データは公式サイトなどからダウンロードして利用します。僕が説明するよりそちらを読んだ方が正確ですね。
Blender世界を作った
公式サイトからLOD1の箱を取ってきてインポートすると、箱がたくさん置けます。
上のイメージ図では更に東京タワーも置いています。東京タワーの比較的詳細なモデルですが、LOD2のデータから、東京タワー周辺を手作業で残した上で、FBXに一度エクスポートして用意しました (データをある程度かためておくため)。
こうして作った世界がこちらです。
Plateauのデータから読み込んできたBLDがたくさん読み込まれています。
けど…
ここまでは良かったのですが、建物が浮いているに気づきませんでした。なんとなく建物が置かれているところが
ゲーム画面でも浮いてますね。
ここで「困ったなぁ」となり、高さ情報も取得するようにしました。
数値標高モデルの導入
土地の情報が必要になる気がします。そこで調べてみると、数値標高モデルというものがあり、このデータも使えるようでした。
数値標高モデルの解説です。
最近データも増えてきている様子ですね。
PlateauのデータでもこのDEMデータはダウンロードできたので、世界に導入してみました。地面データができたのでそれっぽくなってきましたね。
ここまで来ると、建物が浮いておらず、ある程度の土地情報もあり、この世界をソコソコ使えそうな状態になりました。
高さ情報を取得する
実際に作ったプチ世界の上でデータ処理をやってみた話をします。
最初に、Google Street Viewの画像と、Blenderで作った世界との対応関係について述べました。似たようなデータ処理で、Google Mapなどの位置情報をBlenderの世界と対応付けたいときがあります。
Google Mapの座標値(緯度経度)とBlenderの直交座標の対応付けは、公式サイトにpyprojなどを使った処理が紹介されています。Blenderに内蔵されているPythonにpyprojをインストールすると、自動処理で使うことができます。
例えばLOD2モデルの東京タワー周辺の道路ネットワークから取得した地点を考えます。
import pyproj
import json
# WGS84 -> plane 9
trans = pyproj.Transformer.from_crs(6697, 6677)
# ここに地点が入っている
fn = "###"
data = json.load(open(fn, "r"))
N = len(data["nodes"])
for i in range(N):
lat_i, lon_i = data["nodes"][i]
# FBXを読み込むときに縮尺が0.01にしたので0.01倍する
new_y_i, new_x_i = trans.transform(lat_i, lon_i)
new_x_i *= 0.01
new_y_i *= 0.01
# 処理
まずはMatplotlibで可視化してみます。
各地点(◯)の高さを取得できるのかやってみます。頂点の(X, Y)座標から、Z軸のマイナス方向に光線を打ち、情報をファイルに書き出します。
# ray to bottom (適当な高さから下へ)
depsgraph = C.evaluated_depsgraph_get()
vec_point = Vector([new_x_i, new_y_i, 0.2])
dir = Vector([0, 0, -0.01])
# 当たれば(x, y, z)を適当なfpへ保存する
ray = C.scene.ray_cast(depsgraph, vec_point, dir)
if ray[0]:
Z = ray[1][2]
fp.write(f"{lat_i},{lon_i},{Z}\n")
当たった地点の高さを記録したファイルを再度読み込んで、3次元散布図で可視化します。
だいたいの場所からそれっぽいデータが取れた気がします!
もちろん、そこまで正確ではない気がするので、参考までに使うことにしましょう。精度高いデータが必要なときは、Google MapsのAPIなどを使うと良いでしょうか。
まとめ
来年はもっと3D都市モデルデータを真面目に使えるようになりたいですね。
Discussion