コンテンツにスキップ

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に置き換えるまで、期待通りに動作しません。