AMCI Develop Note #00 PLATEAUモデルを表示するまで
はじめに
本解説ではPLATEAUで公開しているCityGML(OBJ)データをWebサイト上で使用する方法を、AMCIでの事例を参考に説明していきます。本解説では3DとHTML、JavaScript(Three.js)の基礎的な知識が必要です。予めご注意ください。
AMCI
本解説における推奨の開発環境は以下の通りです。
- OS: Windows10、MacOS10
- CPU: Corei7 相当
- GPU: GTX1060 相当
- メモリ: 8GB
- ブラウザ: 最新のGoogle Chrome、Microsoft Edge など
※上記以上のスペックを推奨しています
データのダウンロード
データは G空間情報センター(https://www.geospatial.jp/gp_front/) のサイトからダウンロードを行います。本解説では東京駅周辺のエリアをサンプルとして利用します。
東京都のOBJデータの公開ページは下記リンクを参照ください。
3D都市モデル(Project PLATEAU)東京都23区(OBJ 4次メッシュ 2020年度)
https://www.geospatial.jp/ckan/dataset/plateau-tokyo23ku-obj4-2020
ページ内の「東京都23区構築範囲拡大図2/4」を選択すると、東京23区の北東エリアを区切ったマップが表示されます。この中の東京駅付近の番号を探します。
大丸有と名前がつけられたエリアの「53394611」のデータを利用したいので、このデータのダウンロードページ(533946)へ移動し、ページ右上のダウンロードボタンをクリックします。
データの解凍
ダウンロードしたzipデータを解凍すると、下記のようなデータが含まれているので、その中からLOD1.zipを解凍しそのフォルダをクリックします。この中にはエリア毎に細かく分かれた建物のデータが含まれます。続いてこのデータをブラウザ上で表示してみます。
Zipデータに含まれるもの
- brid.zip: 橋や陸橋などのデータ
- dem.zip: 数値標高モデル(地面データ)
- LOD1.zip: 簡略化した建物データ
- LOD2.zip: 形状が細かくテクスチャも付いた建物データ
3Dデータの調整
ダウンロードした3Dデータをブラウザで表示する前に、3Dデータの座標を調整する必要があります。PLATEAUの3Dモデルは細かくエリアやカテゴリ(ビル、地面、橋など)に分かれており、それらは組み合わせることで街の再現などが行なえます。
ここで、1点問題があります。
単純に1つの区画だけをブラウザなどで表示する場合は、3Dモデルの左右と奥行きの座標が中央から離れているため、そのまま表示させようと思っても画面外に表示されてしまいます。
なので、一度3Dソフトなどでデータを開き、中央に座標を移動させたデータをJavaScriptなどで読み込む必要があります。
具体的な手順はここでは割愛しますが、Blenderなどの3Dソフトで調整を行った上で利用をおすすめします。
ブラウザでの表示方法
3Dデータをブラウザで表示するためには、Three.jsという3Dの描画ライブラリを利用します。Three.jsについての説明は下記ページを参照ください。
最新版で学ぶThree.js入門 手軽にWebGLを扱える3Dライブラリ(ics.mediaより)
https://ics.media/entry/14771/
続いて、Three.jsの使い方を説明します。まずはThree.jsライブラリを読み込む必要があるのでこちらのファイル( https://threejs.org/build/three.js )をご自分のPCにダウンロードしてください。次にダウンロードしたthree.jsファイルと同じ階層に、下記のHTMLを作成します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script src="three.js"></script>
<script>
// ここにコードを記述します
</script>
</body>
</html>
このHTMLをGoogle ChromeなどのWebブラウザで開き、エラーなどが出ていなければ準備完了です。
OBJデータを表示する
Three.jsでOBJデータを扱うには、OBJ loaderというクラスを読み込む必要があります。こちらはThree.jsの拡張機能のようなもので、他にもFBX loaderやFont loaderなど様々なものが用意されています。
こちらはGitHubのThree.jsのリポジトリ内からダウンロードができますが、最近のバージョンはWebpackなどでの利用を想定して作られているので、今回のサンプルでは過去バージョンのOBJ loaderを使用します。ファイルはサンプルに含めているので、そちらからご利用ください。
使用例: OBJ loader
https://threejs.org/examples/#webgl_loader_obj
<script src="three.js"></script>
<script src="OBJLoader.js"></script>
上記のようにスクリプトの読み込みに1行加えます。必ずThree.js本体の読み込みの後に行うようにしてください。
そして下記がThree.jsでPLATEAUの3Dモデルを描画するソースコードです。行っている処理についてはコメントを参照してください。
また、最近のGoogle Chromeでは「file:///Users/〜」などではじまるアドレスではデータ(3Dデータなど)の読み込みが行えないので、ローカル環境で動作させたい場合はローカルホストを立てる必要があります。
PythonやPHPから、「python -m SimpleHTTPServer 8000」や「php -S localhost:8000」などのコマンドで簡単にローカルホストを立てる事ができます。ご利用の環境によってコマンドは違う可能性もあるので、ご自身の環境で動作するコマンドをお試しください。
<script>
// 変数の用意
let container;
let camera, scene, renderer;
let mouseX = 0, mouseY = 0;
let windowHalfX = window.innerWidth / 2;
let windowHalfY = window.innerHeight / 2;
let object;
init();
animate();
function init() {
// HTMLにCanvasを追加
container = document.createElement('div');
document.body.appendChild(container);
// カメラを追加
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 250;
// scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0x333333);
// ライトを追加
const ambientLight = new THREE.AmbientLight(0xcccccc, 0.4);
scene.add(ambientLight);
const pointLight = new THREE.PointLight(0xffffff, 0.8);
camera.add(pointLight);
scene.add(camera);
// 地面を追加
const geometry = new THREE.PlaneGeometry( 1000, 1000 );
const material = new THREE.MeshBasicMaterial( {color: 0x666666, side: THREE.DoubleSide} );
const plane = new THREE.Mesh( geometry, material );
plane.rotation.x = 90 * Math.PI / 180;
scene.add( plane );
// 3Dモデルを読み込み
const loader = new THREE.OBJLoader();
loader.load('model/53394610_bldg_6677_center.obj', function(obj) {
object = obj;
object.scale.x = 0.3;
object.scale.y = 0.3;
object.scale.z = 0.3;
scene.add(object);
});
// レンダラーを追加
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
// イベントを追加
document.addEventListener('mousemove', onDocumentMouseMove);
window.addEventListener('resize', onWindowResize);
}
// ブラウザのリサイズ時に実行
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// マウスムーブ時に実行
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 2;
mouseY = (event.clientY - windowHalfY) / 2;
}
// 毎フレーム実行
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.position.x += (mouseX - camera.position.x) * .05;
camera.position.y += (-mouseY - camera.position.y) * .05;
camera.lookAt(new THREE.Vector3(0, 10, 0));
renderer.render(scene, camera);
}
</script>
Author And Source
この問題について(AMCI Develop Note #00 PLATEAUモデルを表示するまで), 我々は、より多くの情報をここで見つけました https://qiita.com/ProjectPLATEAU/items/a5a64d681045ea2f76b6著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .