はじめに
- deck.glを用いてGoogleのPhotorealistic 3D Tilesを表示する方法は下記の記事に書きました。
- 今回の記事では、MapLibre GL JSとdeck.glを用いて、GoogleのPhotorealistic 3D Tilesを表示する方法について説明します。
前提条件
- Google Maps PlatformのAPIキーを取得済みであること。
※Google Maps Platform APIキーの取得・発行についてはこちらを参照してください。
https://www.zenrin-datacom.net/business/gmapsapi/api_key/index.html
deck.glのレイヤーをMapLibre GL JSに組み込む方法
- MapLibre GL JSでGoogleのPhotorealistic 3D Tilesを表示するためには、deck.glのTile3DLayerを使用する必要があります。
- deck.glのTile3DLayerをMapLibre GL JSに組み込むには主に3つの方法があるようです。
- 下記のブログ記事に詳しく書かれています(おすすめは方法2とのこと📝)。
- 方法1、方法2及び方法3について紹介します。
方法1:MapboxOverlayを使ったオーバーレイ
方法2:MapboxOverlayを使ったインターリーブ(おすすめ📝)
- オーバーレイ、インターリーブの違いはこちらのページの図がわかりやすいです。
- オーバーレイは、2つのライブラリが相互に独立してレンダリングを管理する仕様のようです。
- 一方で、インターリーブは、deck.glのレイヤーとMapLibre GL JSのレイヤーのオクルージョンが可能になるようです(方法2がおすすめな理由はここにありそうです📝)。
方法3:MapboxLayerを使ったインターリーブ
- 方法3は、上記の方法2に近い仕様のようです(オクルージョンが可能かなどは試して確認したいところです)。
MapboxOverlayを使ったオーバーレイ
- Google Maps PlatformのAPIキーは、ご自身で用意してください。
- GoogleのPhotorealistic 3D Tilesの表示には、deck.glのMapboxOverlay及びTile3DLayerを使用します。
- MapboxOverlayのオーバーレイは、interleavedをfalseにすることで機能するようです。
- map.addControlでdeck.glのレイヤーをMapLibre GL JSのコントロールとして追加できるようです。
コード
<html>
<head>
<title>Google 3D tiles example</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js"></script>
<link href="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css" rel="stylesheet">
<script src="https://unpkg.com/deck.gl@latest/dist.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
#credits {
position: absolute;
bottom: 0;
right: 0;
padding: 2px;
font-size: 15px;
color: white;
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
z-index: 1000;
}
#credits a {
color: white;
pointer-events: auto;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="credits"></div>
<script type="text/javascript">
// 【参考】https://developers.google.com/maps/documentation/tile/use-renderer?hl=ja
const GOOGLE_API_KEY = 'YOUR_API_KEY';
const TILESET_URL = `https://tile.googleapis.com/v1/3dtiles/root.json`;
const creditsElement = document.getElementById('credits');
const map = new maplibregl.Map({
container: 'map',
style: {
version: 8,
sources: {},
layers: []
},
hash: true,
zoom: 16,
center: [139.7660988, 35.6808658],
pitch: 60,
bearing: 0,
attributionControl: false,
})
// ズーム・回転
map.addControl(new maplibregl.NavigationControl());
// フルスクリーンモードのオンオフ
map.addControl(new maplibregl.FullscreenControl());
// 現在位置表示
map.addControl(new maplibregl.GeolocateControl({
positionOptions: {
enableHighAccuracy: false
},
fitBoundsOptions: { maxZoom: 18 },
trackUserLocation: true,
showUserLocation: true
}));
// スケール表示
map.addControl(new maplibregl.ScaleControl({
maxWidth: 200,
unit: 'metric'
}));
map.on('load', () => {
// MapboxOverlayを使ったオーバーレイ
const overlay = new deck.MapboxOverlay({
interleaved: false,
layers: [
new deck.Tile3DLayer({
id: 'google-3d-tiles',
data: TILESET_URL,
loadOptions: {
fetch: {
headers: {
'X-GOOG-API-KEY': GOOGLE_API_KEY
}
}
},
onTilesetLoad: tileset3d => {
tileset3d.options.onTraversalComplete = selectedTiles => {
const credits = new Set();
selectedTiles.forEach(tile => {
const { copyright } = tile.content.gltf.asset;
copyright.split(';').forEach(credits.add, credits);
creditsElement.innerHTML = [...credits].join('; ');
});
return selectedTiles;
}
}
})
]
});
map.addControl(overlay);
})
</script>
</body>
</html>
MapboxOverlayを使ったインターリーブ
- Google Maps PlatformのAPIキーは、ご自身で用意してください。
- GoogleのPhotorealistic 3D Tilesの表示には、deck.glのMapboxOverlay及びTile3DLayerを使用します。
- MapboxOverlayのインターリーブは、interleavedをtrueにすることで機能するようです。
- map.addControlでdeck.glのレイヤーをMapLibre GL JSのコントロールとして追加できるようです。
コード
<html>
<head>
<title>Google 3D tiles example</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js"></script>
<link href="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css" rel="stylesheet">
<script src="https://unpkg.com/deck.gl@latest/dist.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
#credits {
position: absolute;
bottom: 0;
right: 0;
padding: 2px;
font-size: 15px;
color: white;
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
z-index: 1;
}
#credits a {
color: white;
pointer-events: auto;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="credits"></div>
<script type="text/javascript">
// 【参考】https://developers.google.com/maps/documentation/tile/use-renderer?hl=ja
const GOOGLE_API_KEY = 'YOUR_API_KEY';
const TILESET_URL = `https://tile.googleapis.com/v1/3dtiles/root.json`;
const creditsElement = document.getElementById('credits');
const map = new maplibregl.Map({
container: 'map',
style: {
version: 8,
sources: {},
layers: []
},
hash: true,
zoom: 16,
center: [139.7660988, 35.6808658],
pitch: 60,
bearing: 0,
attributionControl: false,
})
// ズーム・回転
map.addControl(new maplibregl.NavigationControl());
// フルスクリーンモードのオンオフ
map.addControl(new maplibregl.FullscreenControl());
// 現在位置表示
map.addControl(new maplibregl.GeolocateControl({
positionOptions: {
enableHighAccuracy: false
},
fitBoundsOptions: { maxZoom: 18 },
trackUserLocation: true,
showUserLocation: true
}));
// スケール表示
map.addControl(new maplibregl.ScaleControl({
maxWidth: 200,
unit: 'metric'
}));
map.on('load', () => {
// MapboxOverlayを使ったインターリーブ
const overlay = new deck.MapboxOverlay({
interleaved: true,
layers: [
new deck.Tile3DLayer({
id: 'google-3d-tiles',
data: TILESET_URL,
loadOptions: {
fetch: {
headers: {
'X-GOOG-API-KEY': GOOGLE_API_KEY
}
}
},
onTilesetLoad: tileset3d => {
tileset3d.options.onTraversalComplete = selectedTiles => {
const credits = new Set();
selectedTiles.forEach(tile => {
const { copyright } = tile.content.gltf.asset;
copyright.split(';').forEach(credits.add, credits);
creditsElement.innerHTML = [...credits].join('; ');
});
return selectedTiles;
}
},
beforeId: 'admin_labels'
})
]
});
map.addControl(overlay);
})
</script>
</body>
</html>
MapboxLayerを使ったインターリーブ
- Google Maps PlatformのAPIキーは、ご自身で用意してください。
- GoogleのPhotorealistic 3D Tilesの表示には、deck.glのMapboxLayer及びTile3DLayerを使用します。
- map.addLayerでdeck.glのレイヤーがMapLibre GL JSのカスタムスタイルレイヤー(よくわかっていません・・・)として追加されるようです。
コード
<html>
<head>
<title>Google 3D tiles example</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js"></script>
<link href="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css" rel="stylesheet">
<script src="https://unpkg.com/deck.gl@latest/dist.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
#credits {
position: absolute;
bottom: 0;
right: 0;
padding: 2px;
font-size: 15px;
color: white;
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
z-index: 1;
}
#credits a {
color: white;
pointer-events: auto;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="credits"></div>
<script type="text/javascript">
// 【参考】https://developers.google.com/maps/documentation/tile/use-renderer?hl=ja
const GOOGLE_API_KEY = 'YOUR_API_KEY';
const TILESET_URL = `https://tile.googleapis.com/v1/3dtiles/root.json`;
const creditsElement = document.getElementById('credits');
const map = new maplibregl.Map({
container: 'map',
style: {
version: 8,
sources: {},
layers: []
},
hash: true,
zoom: 16,
center: [139.7660988, 35.6808658],
pitch: 60,
bearing: 0,
attributionControl: false,
})
// ズーム・回転
map.addControl(new maplibregl.NavigationControl());
// フルスクリーンモードのオンオフ
map.addControl(new maplibregl.FullscreenControl());
// 現在位置表示
map.addControl(new maplibregl.GeolocateControl({
positionOptions: {
enableHighAccuracy: false
},
fitBoundsOptions: { maxZoom: 18 },
trackUserLocation: true,
showUserLocation: true
}));
// スケール表示
map.addControl(new maplibregl.ScaleControl({
maxWidth: 200,
unit: 'metric'
}));
map.on('load', () => {
const { MapboxLayer, Tile3DLayer } = deck;
// MapboxLayerを使ったインターリーブ
const tile3dLayer = new MapboxLayer({
id: 'google-3d-tiles',
type: Tile3DLayer,
data: TILESET_URL,
loadOptions: {
fetch: {
headers: {
'X-GOOG-API-KEY': GOOGLE_API_KEY
}
}
},
onTilesetLoad: tileset3d => {
tileset3d.options.onTraversalComplete = selectedTiles => {
const credits = new Set();
selectedTiles.forEach(tile => {
const { copyright } = tile.content.gltf.asset;
copyright.split(';').forEach(credits.add, credits);
creditsElement.innerHTML = [...credits].join('; ');
});
return selectedTiles;
}
}
});
map.addLayer(tile3dLayer);
})
</script>
</body>
</html>
参考文献