[Bug] The Cesium Google 3D Tiles endpoint provides an _incorrect_ url for the Tile3dLayer to use with the CesiumIonLoader
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 14.6k
- Forks
- 2.3k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 42
Description
Description
I’m trying to load Google 3DTiles as a MapBoxLayer using Tile3DLayer and CesiumIonLoader.
using:
const CesiumLayer= new MapboxLayer({
id: 'tiles',
type: Tile3DLayer,
data: 'https://assets.ion.cesium.com/2275207/tileset.json', //Google 3DTiles asset
loader: CesiumIonLoader,
loadOptions: {
'cesium-ion': {accessToken: 'AccessToken'}
},
output this error:
Uncaught (in promise) Error: loader assertion failed.
at assert (assert.ts:7:11)
at getIonTilesetMetadata (ion.ts:23:3)
at async Tile3DLayer._loadTileset (tile-3d-layer.ts:188:30)
Looking at the Cesium endpoint API, I can see that the result is of type 3DTiles, however is not formatted as the usual Cesium asset, but the URL is nested in a options object
{
"type": "3DTILES",
"externalType": "3DTILES",
"options": {
"url": "https://tile.googleapis.com/v1/3dtiles/root.json?key=<KEY>"
},
"attributions": [
{
"html": "<span><a href=\"https://cesium.com\" target=\"_blank\"><img alt=\"Cesium ion\" src=\"https://assets.ion.cesium.com/ion-credit.png\"></a></span>",
"collapsible": false
},
{
"html": "<a href=\"https://cesium.com/pricing/\" target=\"_blank\">Upgrade for commercial use.</a>",
"collapsible": false
},
{
"html": "<span><img alt=\"Google\" src=\"https://assets.ion.cesium.com/google-credit.png\"></span>",
"collapsible": false
}
]
}
the usual Cesium asset response is this:
{
"type": "3DTILES",
"url": "https://assets.ion.cesium.com/us-east-1/asset_depot/96188/OpenStreetMap/2023-01-02/tileset.json?v=16",
"accessToken": "<ACCESS Token>",
"attributions": [
{
"html": "<span><a href=\"https://cesium.com\" target=\"_blank\"><img alt=\"Cesium ion\" src=\"https://assets.ion.cesium.com/ion-credit.png\"></a></span>",
"collapsible": false
},
{
"html": "<a href=\"https://cesium.com/pricing/\" target=\"_blank\">Upgrade for commercial use.</a>",
"collapsible": false
},
{
"html": "<span>© <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">OpenStreetMap</a> contributors</span>",
"collapsible": true
}
]
}
Changing the data to that URL, and removing the Loader and load options makes everything work as expected.
const CesiumLayer= new MapboxLayer({
id: 'tiles',
type: Tile3DLayer,
data: 'https://tile.googleapis.com/v1/3dtiles/root.json?key=<KEY>'
)}
I suspect the issue lies with Deck.gl’s Tile3DLayer, and not with the Loader.gl’s CesiumIonLoader (well, the issue is actually the response from Cesium).
A solution would be for the Tile3DLayer to check if url exists in the response, if not look at options.url and ignore CesiumIonLoader.
Flavors
- Script tag
- React
- Python/Jupyter notebook
- MapboxOverlay
- GoogleMapsOverlay
- CartoLayer
- ArcGIS
Expected Behavior
Tile3DLayer should handle the Cesium response and visualise the Google 3D tiles.
Steps to Reproduce
JS
import {MapboxLayer} from '@deck.gl/mapbox';
import { CesiumIonLoader } from '@loaders.gl/3d-tiles';
import mapboxgl from 'mapbox-gl';
import {Tile3DLayer} from '@deck.gl/geo-layers';
import {Deck, log} from '@deck.gl/core';
const INITIAL_VIEW_STATE = {
longitude: -0.12599998138976254, //0.12,
latitude: 51.521592969384706, //51.5,
zoom: 15,
bearing: 0,
pitch: 0
};
// Set your API key here
const API_TOKEN_Mapbox = 'TOKEN';
mapboxgl.accessToken = API_TOKEN_Mapbox;
// MapBox Vector Tile
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/dark-v10',
interactive: true,
center: [INITIAL_VIEW_STATE.longitude, INITIAL_VIEW_STATE.latitude],
zoom: INITIAL_VIEW_STATE.zoom,
bearing: INITIAL_VIEW_STATE.bearing,
pitch: INITIAL_VIEW_STATE.pitch
});
map.on('load', () => {
const CesiumLayer= new MapboxLayer({
id: 'tiles',
type: Tile3DLayer,
data: 'https://assets.ion.cesium.com/2275207/tileset.json',
loader: CesiumIonLoader,
loadOptions: {
'cesium-ion': {accessToken: '<TOKEN>'}
},
},
});
map.addLayer(CesiumLayer);
});
HTML
<body>
<div id="app">
<div id="container">
<div id="map"></div>
</div>
</div>
</body>
CSS
body {
margin: 0;
padding: 0;
}
#container {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
Environment
- Framework version:
- Deckgl 8.9.0
- Loaders.gl/3d-tiles 3.4.14 (4.0.4 gave me a contex._parse error)
- MapboxGL 3.1.0
- Browser: Chromium
- OS: Win
Logs
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with ion.ts and tile-3d-layer.ts at the failing getIonTilesetMetadata and _loadTileset calls, using the provided MapboxLayer reproduction to inspect the Cesium response. Confirm that Google’s nested options.url is handled without the loader assertion and that the Tile3DLayer renders the tiles successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- data-visualization, frontend, web-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100