はじめに
本エントリーは deck.gl Advent Calendar 2021 19日目の記事です。
ArcGIS と deck.gl の連携について紹介したいと思います。
Esri が提供している ArcGIS API for JavaScript からカスタムレイヤーとして deck.gl が提供している機能を使用することができるようになっています。
developers.arcgis.com
過去に以下の記事で紹介しています。
freedom-tech.hatenablog.com
また、deck.gl からは ArcGIS の 3D データモデルを表示することができるようになっています。 ArcGIS の 3D データモデルは、オープンスタンダートの Open Geospatial Consortium(OGC) にも準拠しており、3D GIS データを扱うための各種フォーマットをシーン サービスと呼ばれる I3S 形式で提供しています。
こちらも過去に以下の記事で紹介しています。 freedom-tech.hatenablog.com
今回は前回紹介したときから deck.gl と ArcGIS API for JavaScript のバージョンをアップしていますので、改めて新しい情報を含めて紹介したいと思います。
deck.gl とは
世界最大の配車アプリを開発・運営する Uber 社 がオープンソースとして公開しているデータビジュアライゼーションフレームワークです。現在は、Uber 社から離れてオープンなプロジェクト vis.gl Technical Steering Committee(TSC) として運用されているようです。
ArcGIS API for JavaScript で deck.gl のレイヤーを表示
ArcGIS API for JavaScript の現在の最新バージョンは、4.22 ですが、deck.gl のレイヤーも呼び出して使用することができるようになっています。ArcGIS API for JavaScript から deck.gl を利用する方法については、それぞれ以下のガイドから確認することができます。
deck.gl と ArcGIS API for JavaScript のレイヤーを使用したサンプルアプリです。
作成したアプリのサンプルソースは以下になります。GeoJSON は、ArcGIS API for JavaScript と deck.gl でも扱うことができるようになっていますが、今回は、ArcGIS API for JavaScript の GeoJSON レイヤークラスを使用しました。
<html> <head> <!-- deck.gl standalone bundle --> <script src="https://unpkg.com/deck.gl@latest/dist.min.js"></script> <script src="https://unpkg.com/@deck.gl/arcgis@latest/dist.min.js"></script> <!-- ArcGIS dependencies --> <link rel="stylesheet" href="https://js.arcgis.com/4.22/esri/themes/light/main.css"/> <script src="https://js.arcgis.com/4.22/"></script> <style type="text/css"> body {margin: 0; padding: 0;} #container {width: 100vw; height: 100vh;} </style> </head> <body> <div id="container"></div> </body> <script type="text/javascript"> const {loadArcGISModules} = deck; // source: Natural Earth http://www.naturalearthdata.com/ via geojson.xyz const COUNTRIES = 'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_admin_0_scale_rank.geojson'; //eslint-disable-line const AIR_PORTS = 'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_10m_airports.geojson'; loadArcGISModules(['esri/Map', 'esri/views/MapView', "esri/layers/GeoJSONLayer"]).then(({DeckLayer, modules}) => { const [ArcGISMap, MapView, GeoJSONLayer] = modules; const layer = new DeckLayer({ 'deck.layers': [ new deck.GeoJsonLayer({ id: 'airports', data: AIR_PORTS, // Styles filled: true, pointRadiusMinPixels: 2, pointRadiusScale: 2000, getPointRadius: f => (11 - f.properties.scalerank), getFillColor: [200, 0, 80, 180], // Interactive props pickable: true, autoHighlight: true, onClick: info => info.object && alert(`${info.object.properties.name} (${info.object.properties.abbrev})`) }), new deck.ArcLayer({ id: 'arcs', data: AIR_PORTS, dataTransform: d => d.features.filter(f => f.properties.scalerank < 4), // Styles getSourcePosition: f => [-0.4531566,51.4709959], // London getTargetPosition: f => f.geometry.coordinates, getSourceColor: [0, 128, 200], getTargetColor: [200, 0, 80], getWidth: 1 }) ] }); const geojsonLayer = new GeoJSONLayer({ url: COUNTRIES, opacity: 0.3, copyright: "COUNTRIES" }); // In the ArcGIS API for JavaScript the MapView is responsible // for displaying a Map, which usually contains at least a basemap. // eslint-disable-next-line const mapView = new MapView({ container: 'container', map: new ArcGISMap({ basemap: 'dark-gray-vector', layers: [layer, geojsonLayer] }), center: [0.119167, 52.205276], zoom: 5 }); }); </script> </html>
使用したサンプルアプリは以下の GitHub にも公開しています。 github.com
deck.gl で i3S の 3D データを表示
次に deck.gl から ArcGIS の 3D データモデルを表示する場合に loaders.gl というライブラリを使用します。
現在の最新バージョンが、バージョン 3.1 でいくつか更新されていますが、ArcGIS に関係しそうなところですと、@loaders.gl/i3s が、KTX2-Basis のテクスチャに対応したそうです。
さっそく、テクスチャに対応した i3S の 3D モデルのデータを deck.gl で表示したいと思います。今回は東京都の千代田区の 3D モデルを使用します。以下のサイトから千代田区の 3D Tiles のデータをダウンロードします。
ダウンロードした 3DTiles のデータを i3S へと変換するために Tile Converter を使用します。
loaders.gl
Tile Converter を最初にインストールします。
$npm i @loaders.gl/tile-converter $npx tile-converter --install-dependencies
そして、ダウンロードした 3D Tiles を i3S へと変換するために以下のコマンドを実行します。
$npx tile-converter --input-type 3DTILES --tileset ./13101_chiyoda-ku/tileset.json --name 13101_chiyoda-ku --output ./13101_chiyoda-ku_output --slpk
変換に成功すると 13101_chiyoda-ku.slpk という SLPK 形式のファイルが作成されますので、それを ArcGIS のプラットフォームに登録します。
ArcGIS に 13101_chiyoda-ku.slpk を登録することで、シーンサービスとして作成されます。 以下に ArcGIS に登録した 13101_chiyoda-ku.slpk をシーンビューワーでご覧いただけます。
www.arcgis.com
最後に作成されたシーンサービスを deck.gl から表示してみます。以下の URL が REST のエンドポイントとして、作成されますので、この URL を指定します。 https://tiles.arcgis.com/tiles/HzGpeRqGvs5TMkVr/arcgis/rest/services/13101_chiyoda_ku/SceneServer/layers/0
千代田区の 3D モデルを表示したサンプルアプリです。
作成したアプリのサンプルソースは以下になります。
import {loadArcGISModules} from '@deck.gl/arcgis'; import {Tile3DLayer} from '@deck.gl/geo-layers'; import {I3SLoader} from '@loaders.gl/i3s'; // Tileset entry point: Indexed 3D layer file url const TILESET_URL = 'https://tiles.arcgis.com/tiles/HzGpeRqGvs5TMkVr/arcgis/rest/services/13101_chiyoda_ku/SceneServer/layers/0' export async function renderToDOM(container) { const {DeckRenderer, modules} = await loadArcGISModules([ 'esri/Map', 'esri/views/SceneView', 'esri/views/3d/externalRenderers' ]); const [ArcGISMap, SceneView, externalRenderers] = modules; const sceneView = new SceneView({ container, qualityProfile: 'high', map: new ArcGISMap({ basemap: 'dark-gray-vector' }), environment: { atmosphereEnabled: false }, camera: { position: {x: 139.7673068, y: 35.6809591, z: 3000}, heading: 0, tilt: 25 }, viewingMode: 'local' }); const renderer = new DeckRenderer(sceneView, {}); externalRenderers.add(sceneView, renderer); sceneView.on('layerview-create', () => { renderer.deck.layers = [ new Tile3DLayer({ id: 'tile-3d-layer', data: TILESET_URL, loader: I3SLoader }) ]; }); return { remove: () => { sceneView.destroy(); renderer.dispose(); } }; }
作成したサンプルアプリ一式は以下の GitHub にも公開しています。 github.com
さいごに
deck.gl や loaders.gl はオープンソースなので、ArcGIS 製品を使用しなくても i3S のデータを扱うことができるのは大変便利ですね。前回紹介したときよりも i3S の対応が格段によくなっており、3DTiles や i3S が手軽に使用できる環境になっているのではないかと思いました。今後も deck.gl、loaders.gl ともにバージョンアップもされていくので今後の機能拡張に期待できますね。