13
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

3Dモデルを3DTilesに変換してdeck.glで表示する

Posted at

やりたいこと

Mapbox GL JS、deck.glのような2.5次元表現ができるWebGISや、Cesium、iTownsといった3次元WebGIS上への3Dモデル配置の要望をよく聞くようになりました。
2020年4月に公開された国土交通データプラットフォームでも、Mapbox GL JS/deck.glを使用した点群データの表示が行われています。今後さらに事例は増えてくると思われます。
国土交通データプラットフォーム

点群データの場合は、計測時の地理座標が付いてさえいれば、deck.glに単体のデータとして読み込むことや、3DTilesに変換した上で読み込むことができます。
一方、構造物の3DモデルをglTF、objで受け取った際は、地理座標はついていないし、方向はわからないし、苦労して単体のモデルを配置することになります。ジオリファレンスが必要なのですが、どういう手順が一番いいのか試行錯誤です。
特に迷うのが、3DTilesで扱いたい際にどうやって変換しようという点でした。

この記事は、適当な3Dモデルを強引に3DTilesに変換していい感じにdeck.glに配置してみたものです。たぶん、こんな方法じゃなく楽にできる方法があると思います。

BlenderGIS

インストール

まずは位置合わせを行いたいのですが、ここではBlenderのaddon「BlenderGIS」を使用します。
Blenderに各種GISフォーマットをインポートできたり、DEMを読み込み3D表示ができるのですが、ここでの目的はWEBメルカトル座標を定義して、GoogleMap等のWeb地図を読み込むことです。WEBメルカトル座標上で3Dモデルを配置します。

Install and usageを参考に、githubからソースのダウンロードを行い、addonへインストールします。

Quick startの2.に書かれていますが、「cache folder」を指定しておきます。また、「spatial reference systems」が「Web Mercator」になっていることも確認しておきましょう。

GoogleMap表示

インストールが完了すると、3Dビューウィンドウ上に「GIS」が追加されますので、「GIS」から「Web Geodata」→「Basemap」の順に選択を行います。
GIS.png

Source:Google
Layer:Map
を選択して「OK」をクリックします。
googlemap.png

GoogleMapが表示されますので、ドラッグで移動、マウスホイールで拡大/縮小を行い、モデルを配置したい位置まで地図を移動します。移動が終わったら、「E」キーを押すことでtextured plane meshが作成されます。

この時に地図の中心とした位置の緯度経度は調べておきましょう。後で3DTilesに変換する際に、原点座標として使います。
clip

objの位置合わせ

適当にfree素材のobjを配置してみます。CloudCompareで表示した例ですが、寸法も実寸にはなっていない建物の3Dモデルです。
model.png

Blenderへインポートすると、ちっさいです。
Blenderへインストール

このモデルは拡大したり、回転したり、移動したりして、なんとなく山頭火本店に合わせて配置してみます。
rotate.png

move.png

scale.png

大体いいかなという位置に配置できたら、取り込んだtextured plane meshは削除した上で、建物モデルのみobjにexportしておきます。

obj23dtiles

インストール

objから3DTilesへの変換には、obj23dtilesを使用しました。メンテナンスされてないので注意が必要ですが、tileset.jsonまで作ってくれるので便利です。

インストール自体は、
npm install -g obj23dtiles
で完了です。

変換準備

BlenderGISで地図を切り出した際の中心緯度経度を、customTilesetOptions.jsonに記載しておきます。obj23dtilesで変換する際に、3Dモデルの原点座標(0,0)が緯度経度(ラジアン単位)でいくつかを与えます。
先ほど切り出した地図の場合、緯度:43.764783、経度:142.359914でしたので、これをラジアンに変換して記載します。

customTilesetOptions.json
{
    "longitude":      2.48464922215,
    "latitude":       0.763839559769,
    "transHeight":    0.0,
    "region":         true,
    "box":            false,
    "sphere":         false
}

変換

"Create a single tileset with .b3dm tile and custom tileset options"になるようにオプションを指定して、building.objを入力に3DTilesを作成します。

obj23dtiles -i ./building.obj --tileset -p ./customTilesetOptions.json

変換がうまくいくと、Batchedbuildingフォルダに、tileset.jsonとbuilding.b3dmが作成されます。

deck.glで表示

deck.glの3d-tilesサンプルを変更して表示

deck.glに3d-tiles表示のサンプルがあります。これを少しだけ変更します。
app.js内の_renderTile3DLayer()において、TILESET_URLは作成したtileset.jsonへのパスに、loaderとしてTiles3DLoaderを指定とします。
その他、実行まえに、

export MapboxAccessToken=<mapbox_access_token>

でmapboxのキーを設定することも忘れずに。

app.js
  _renderTile3DLayer() {
    return new Tile3DLayer({
      id: 'tile-3d-layer',
      pointSize: 2,
      data: TILESET_URL,
      loader: Tiles3DLoader,
      loadOptions: {"_lighting": "pbr"},
      onTilesetLoad: this._onTilesetLoad.bind(this)
    });
  }

描画してみると、大体いい位置にモデルを表示できています。
deckgl3.png

declgl2.png
13
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?