LoginSignup
12
11

More than 3 years have passed since last update.

deck.glのTile3dLayerでPLATEAUの3D都市モデルを表示してみた

Last updated at Posted at 2021-04-11

はじめに

今話題のPLATEAUのデータをdeck.gl+Mapbox GL JSで表示してみるぞ!

Tile3dLayer

みんな大好きdeck.glにTile3dLayerというクラスがあり、これはいわゆる3d-tilesを読むためのレイヤーです。

点群でも3Dモデルでも、3d-tilesならこのレイヤーで表示する事が出来ます(一応Experimentalです)。以下のように定義します。


import { Tile3DLayer } from '@deck.gl/geo-layers';
import { Tiles3DLoader } from '@loaders.gl/3d-tiles';

const tile3dLayer = new Tile3DLayer({
    id: 'tile3dlayer',
    pointSize: 1,
    data: 'https://s3-ap-northeast-1.amazonaws.com/3dimension.jp/13000_tokyo-egm96/13101_chiyoda-ku_notexture/tileset.json', // PLATEAU千代田区
    loader: Tiles3DLoader,
    onTilesetLoad: (tileset) => {
        const { cartographicCenter } = tileset;
        const [longitude, latitude] = cartographicCenter;
        console.log(longitude, latitude); // 3dtilesの中心座標を取れるぞ
    },
});

Mapbox GL JS上に表示してみる

deck.glレイヤーをMapbox GL JS上で表示する手法はhttps://deck.gl/docs/api-reference/mapbox/mapbox-layerを見ればわかります。

スクリーンショット 2021-04-11 10.42.24.png

表示は出来ましたがなんかモデルが宙に浮いています(静止画像なのでわかりにくいですがかなり浮いています)。

モデルが浮く問題

PLATEAU-Viewをみてみると、モデルは標高とリンクしている事がわかります。おそらく標高と建物は同時に計測されているのかと思われます。

スクリーンショット 2021-04-11 10.44.18.png

Mapbox GL JSは基本的に平面地図で標高はゼロです(v2なら3D表現ができるが…)。仮に3Dだとしても、PLATEAUで使われている標高データはすぐウェブで使える形式では公開されていないので、やはり基準の標高値がゼロでも、マシな見た目にする事を考えた方がいいでしょう。つまり全体の高度を一律に下げる事を考えます。

標高データはCityGMLで公開されていて中身をみる限りTINなので、何かしらウェブで使える標高データに変換する方法はあるでしょう

高度を調整してみた

さっきのtile3dLayerにオプションを追加します。


import { Tile3DLayer } from '@deck.gl/geo-layers';
import { Tiles3DLoader } from '@loaders.gl/3d-tiles';
import { Vector3 } from 'math.gl';

const tile3dLayer = new Tile3DLayer({
    id: 'tile3dlayer',
    pointSize: 1,
    data: 'https://s3-ap-northeast-1.amazonaws.com/3dimension.jp/13000_tokyo-egm96/13101_chiyoda-ku_notexture/tileset.json',
    loader: Tiles3DLoader,
    onTilesetLoad: (tileset) => {
        const { cartographicCenter } = tileset;
        const [longitude, latitude] = cartographicCenter;
        console.log(longitude, latitude);
    },
    onTileLoad: (tileHeader) => {
        tileHeader.content.cartographicOrigin = new Vector3(
            tileHeader.content.cartographicOrigin.x,
            tileHeader.content.cartographicOrigin.y,
            tileHeader.content.cartographicOrigin.z - 40,
        );
    },
});

タイル単位で保持しているらしい基準標高値を、一律40m下げました。

スクリーンショット 2021-04-11 10.49.43.png

さっきよりも地に足のついた見た目になりましたね。

終わりに

3Dデータを表示するなら素直にCesium使っておいた方が良い気がしていますが、ベクタータイルや2D地図表現はやはりMapbox GL JSの強みだと思います(最近では3D地形も表示出来ますし…)。

12
11
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
12
11