Display 3D Tokyo on the earth¶
Using the B3dTiles format and display 3D Tokyo.
display_3d_building_all_tokyo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Display 3D Tokyo on the earth</title>
<meta property="og:description" content="Using the B3dTiles format and display 3D Tokyo. " />
<script src="./v0.10.1/mapray.min.js"></script>
<script src="./v0.10.1/maprayui.min.js"></script>
<script src="https://unpkg.com/leaflet.vectorgrid@1.3.0/dist/Leaflet.VectorGrid.bundled.min.js"></script>
<script src="https://unpkg.com/jismesh-js/dist/jismesh.min.js"></script>
<link rel="stylesheet" href="./v0.10.1/mapray.css">
<style>
body {margin: 0; padding: 0;}
html, body, div#mapray-container { height: 100%; }
</style>
</head>
<body>
<div id="mapray-container"></div>
</body>
</html>
<script>
function addB3d( urls )
{
const scenes = urls.map(url => {
const provider = new mapray.StandardB3dProvider({ url });
return uiviewer.viewer.b3d_collection.createScene( provider );
});
return scenes;
}
class B3DView extends maprayui.StandardUIViewer {
constructor( container, showCityInfo, options ) {
super( container, options );
this.time = 0.0;
this.showCityInfo = showCityInfo;
}
onMouseUp(point, event) {
super.onMouseUp(point, event);
let msray = this._viewer.camera.getCanvasRay(point);
// レイがあるなら
if (msray !== undefined) {
// レイと交差するオブジェクトを取得
let res = this._viewer?.pickWithRay(msray);
if (res && res.position && res.feature_id) {
const p = new mapray.GeoPoint();
p.setFromGocs(res.position);
const lv = 16;
this.showCityInfo( p.longitude, p.latitude, lv, res.feature_id[0]);
}
}
}
}
const cloudApi = new mapray.cloud.CloudApiV2({
tokenType: mapray.cloud.CloudApi.TokenType.ACCESS_TOKEN,
token: "<YOUR_MAPRAY_ACCESS_TOKEN>"
});
const uiviewer = new B3DView( "mapray-container", showCityInfo, {
dem_provider: new mapray.StandardDemProvider( cloudApi.getDefaultDemAsResource() ),
atmosphere: new mapray.Atmosphere()
} );
uiviewer.viewer.atmosphere.setRayleigh(0.003);
uiviewer.viewer.atmosphere.setMie(0.001);
// Shinbashi Station in Tokyo JP,
uiviewer.setCameraPosition({
longitude: 139.75756686,
latitude: 35.6659950,
height: 300
});
// Tokyo Tower
uiviewer.setLookAtPosition({
longitude: 139.745415619,
latitude: 35.6586504,
height: 200
});
const STANDARD_2_TILES = ["533925", "533926", "533934", "533935", "533936", "533937", "533944", "533945", "533946", "533947", "533954", "533955", "533956", "533957"];
let plateau_urls = STANDARD_2_TILES.map( tile => "https://opentiles.mapray.com/3dcity/" + tile + "/tile-index.json" );
let plateau_attribute_urls = "https://opentiles.mapray.com/mvt/tokyo_bldg";
addB3d(plateau_urls);
async function showCityInfo( longitude , latitude, lv, targetID ) {
const meshCode = jismesh.toMeshCode(latitude, latitude, lv);
const tile = LonLat2Tiles(longitude, latitude, lv);
// MVT Tilesをダウンロードしてデータを構築
const cityMap = await loadCityData(tile[0], tile[1], lv);
const jisconverter = new JisMesh();
const meshLV = 2;
// 標準タイルを取得(クラウドストレージに2次タイルごとに保存されている)
const code = jisconverter.toMeshCode( latitude, longitude, meshLV);
// feature_listのMapのindexが2次タイル
const feature = this._feature_list.get(code);
if (feature) {
// feature_list.jsonのIDと建物IDとのマッピングデータから建物IDを取得
const buildingID = feature.getBuildingID(targetID);
if (buildingID) {
// 建物IDを元に、MVT Tilesから取得したデータ(cityMap)からデータを取得
const cityInfo = cityMap.get(buildingID);
if (cityInfo) {
this._clearTable();
this._buildTable(cityInfo.properties);
if (this._infoEntity) {
this.viewer.scene.removeEntity(this._infoEntity);
this._infoEntity = null;
}
this._infoEntity = this._drawBuildingPin(cityInfo);
}
}
}
}
// MVT TilesをダウンロードしてGeoJSONのデータリスト(TokyoCityMap)を生成する
async function loadCityData( tileX, tileY, zoom ) {
let buffer = null;
try {
buffer = await getMVTTiles(tileX, tileY, zoom);
} catch (err) {
console.log(err);
}
if (buffer) {
const parser = new MvtParser(buffer);
const tokyoMap = parser.parseGeoJSON("bldg", tileX, tileY, zoom);
if (tokyoMap) {
return Promise.resolve(tokyoMap);
}
}
return Promise.reject();
}
// MVT Tilesをダウンロードしてpbfをデコード
async function getMVTTiles( x, y, zoom ) {
const options = {
method: "GET",
mode: "cors",
credentials: "same-origin"
};
let response = await fetch( plateau_attribute_urls + "/" + zoom + "/" + x + "/" + y + ".pbf", options );
if ( response.ok ) {
return response.arrayBuffer();
} else {
throw new Error(response.statusText);
}
}
</script>
Info
このサンプルコードは、<YOUR_MAPRAY_ACCESS_TOKEN>を、あなたのMapray CloudアカウントのOrganization Tokenに置き換えるまで、期待通りに動作しません。