Cesium API endpoint for Google 3D Tiles asset provides an _incorrect_ URL

Not sure if this is the right place for this question, as it is related to the CesiumION API but loaded using LoadersGL in DeckGL (I’ve already posted an issue there as well). When I tried to load the Google 3DTiles using DeckGL 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'}
},

I have the following issue:

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 an options object of the JSON response:

{
    "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}
    ]
}

While 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>'
)}

However, the Google link needs to have the appended token, which is generated during the Cesium authentication step. Therefore, the Cesium loader needs to be called.
I guess one issue is the endpoint that is not formatted as the usual Cesium response, and the CesiumLoader is not able to handle the different response itself.

Hi,

The asset endpoint route can return two different values. One is for Cesium ion hosted assets and the other is for assets hosted by external providers (such as Google). The options are slightly different for each type.

I can see how how this could be easily overlooked since the responses are similar and there is not a field that explicitly identifies if it is an internal or external asset.

Here is a screenshot from the relevant section of the API documentation for the external asset response:

Hopefully this information will help CesiumIonLoader fix the issue on their side so they can support both internal and external assets.

1 Like