deck.glでポイントクラウドを表示する
この記事はdeck.gl Advent Calendar 2021 参加記事です。
概要
最近では、点群データをスキャンできるEveryPointなどのアプリが注目を集めていますが、deck.glを使うとこれらのアプリで撮影したply形式のデータを読み込んでサクッとポイントクラウドとして表示することができます。
また、ローダーを変更することで同様のコードで las/lazデータ のポイントクラウドも表示することができます。
なお、deck.glはポイントクラウド(点群)ではない通常の3Dモデルも表示することができるのですが、それはまた別途記事にします。
サンプルコード
表示しているモデルはiPhoneでてきとうに撮影した駅の自販機です。(スマホだと初回はデータを読み込んでから表示されるまでにちょっと時間がかかります)
解説
loaders.glのPLYLoaderを使ってデータを読み込み、そのデータをPointCloudLayerに渡してポイントクラウドを表示します。
deck.glにOrbitViewを指定し、オブジェクトを中心にカメラが回転するように表示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
//OrbitViewを読み込み import DeckGL, { OrbitView } from "deck.gl"; //PLYローダーを読み込む import { PLYLoader } from "@loaders.gl/ply"; import { load } from "@loaders.gl/core"; //初期カメラ位置の設定 const INITIAL_VIEW_STATE = { target: [0, 0, 0], rotationX: 0, rotationOrbit: 0, minZoom: 0, maxZoom: 10, zoom: 1 }; const App = () => { //plyデータを保管する変数 const [data, setData] = useState(); //カメラの初期設定を行う const [viewState, setViewState] = useState(INITIAL_VIEW_STATE); useEffect(() => { const dataload = async () => { //plyデータを読み込む const res = await load("./data/test.ply", PLYLoader); //読み込んだPLYデータのBounding boxデータを取得する const [mins, maxs] = res.header.boundingBox; //Bounding boxを元にポイントクラウドが画面に収まる位置へカメラを移動する setViewState({ ...INITIAL_VIEW_STATE, target: [ (mins[0] + maxs[0]) / 2, (mins[1] + maxs[1]) / 2, (mins[2] + maxs[2]) / 2 ], zoom: Math.log2(window.innerWidth / (maxs[0] - mins[0])) }); //data変数をupdate setData(res); }; dataload(); }, []); //レンダリング return ( <div className="App"> <DeckGL //OrbitView を指定 views={new OrbitView({ fov: 50 })} initialViewState={viewState} controller={true} layers={renderLayers({ data: data })} parameters={{ clearColor: [0.93, 0.86, 0.81, 1] //ポイントのカラー調整 }} /> </div> ); }; export default App; |
レイヤー側ではplyデータの座標に合わせて、coordinateSystemプロパティで直交座標系(CARTESIAN)を指定します。
1 2 3 4 5 6 7 8 9 |
const layer = new PointCloudLayer({ id: 'laz-point-cloud-layer', data: data, coordinateSystem: COORDINATE_SYSTEM.CARTESIAN, getNormal: [0, 1, 0], getColor: [255, 255, 255], opacity: 0.5, pointSize: 0.5, }) |
las/lazデータのポイントクラウドデータを読み込みたい場合はloaders.glのLASLoaderを利用してください。