Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] "Cesium OSM Buildings" 3d tiles dataset not working with loaders.gl #3144

Open
tdurand opened this issue Oct 18, 2024 · 2 comments
Open
Labels
bug Something isn't working

Comments

@tdurand
Copy link

tdurand commented Oct 18, 2024

Loader

CesiumIonLoader (Tiles3DLoader)

Description

I am looking to display the OSM Buildings dataset from Cesium using deck.gl (and loaders.gl) (3D tiles data)

Unfortunately nothing displays (no buildings), after some investigation I found out that:

  • Loaders.gl requests properly the tileset.json , but do not go further down
  • The tileset load returns NaN for zoom value (which may be normal as it is a worldwide dataset, not localized somewhere)
  • Moving the map do not trigger any further fetch of tiles from this tileset

When trying to debug, it seems that loaders.gl is not working well with this tileset boundingVolume, and when it checks if it should go deeper just returns without getting down to the child tiles. (some more details here)

Thanks for having a look

Expected Behavior

I would expect OSM buildings to load like on this example of Cesium : https://sandcastle.cesium.com/?src=Cesium%20OSM%20Buildings.html&label=ion%20Assets

image

Steps to Reproduce

Minimal repro based on the loaders.gl example for 3D Tiles: https://github.com/tdurand/test-cesium-osmbuildings/blob/main/app.tsx

Deployed here: https://test-osmbuildings.vercel.app/

export default function App({
  mapStyle = "https://basemaps.cartocdn.com/gl/dark-matter-nolabels-gl-style/style.json",
  updateAttributions,
}: {
  mapStyle?: string;
  updateAttributions?: (attributions: any) => void;
}) {
  const [initialViewState, setInitialViewState] = useState(INITIAL_VIEW_STATE);

  const onTilesetLoad = (tileset: Tileset3D) => {
    // Recenter view to cover the new tileset
    console.log(tileset);
    const { zoom, cartographicCenter } = tileset;
    const [longitude, latitude] = cartographicCenter;

    console.log(longitude);
    console.log(latitude);
    console.log(zoom); // Zoom is NaN
    
    setInitialViewState({
      ...INITIAL_VIEW_STATE,
      longitude: cartographicCenter[0],
      latitude: cartographicCenter[1],
      zoom: zoom || 17,
    }); 
  };

  const tile3DLayer = new Tile3DLayer({
    id: "tile-3d-layer",
    data: "https://assets.ion.cesium.com/96188/tileset.json",
    loader: CesiumIonLoader,
    loadOptions: { "cesium-ion": { accessToken: ION_TOKEN } },
    onTilesetLoad,
  });

  return (
    <DeckGL
      layers={[tile3DLayer]}
      initialViewState={initialViewState}
      controller={true}
    >
      <Map reuseMaps mapStyle={mapStyle} />
    </DeckGL>
  );
}

Environment

  • Framework version: latest
  • Browser: Chrome / Firefox
  • Node: latest stable
  • OS: Windows

Logs

For reference, the root tileset.json content

{
    "asset": {
        "version": "1.0",
        "tilesetVersion": "57181480-e706-11ee-857d-e18e4a3674dc",
        "extras": {
            "ion": {
                "defaultStyle": {
                    "color": "Boolean(${feature['cesium#color']}) ? color(${feature['cesium#color']}) : color('#ffffff')"
                },
                "terrainId": 1,
                "georeferenced": true,
                "movable": false
            }
        }
    },
    "properties": {
        "elementType": {},
        "elementId": {},
        "cesium#color": {},
        "cesium#estimatedHeight": {
            "maximum": 1102,
            "minimum": -16
        },
        "building": {},
        "shop": {},
        "source": {},
        "name": {},
        "wheelchair": {},
        "access": {}
    },
    "extensionsUsed": [
        "3DTILES_batch_table_hierarchy"
    ],
    "geometricError": 154134.67955991725,
    "root": {
        "geometricError": 77067.33977995862,
        "boundingVolume": {
            "region": [
                -3.1415925942485985,
                -1.4599681618940228,
                3.141545370875028,
                1.4502639200680947,
                -385.0565011513918,
                5967.300616082603
            ]
        },
        "content": {
            "uri": "root.b3dm"
        },
        "children": [
            {
                "geometricError": 77067.33977995862,
                "boundingVolume": {
                    "region": [
                        -3.1415925942485985,
                        -1.4599681618940228,
                        0.00003951949025290761,
                        1.4502639200680947,
                        -165.10238794752343,
                        5915.2067650589615
                    ]
                },
                "content": {
                    "uri": "0-0-0.json"
                }
            },
            {
                "geometricError": 77067.33977995862,
                "boundingVolume": {
                    "region": [
                        -0.00003125012025695847,
                        -1.4035456116211558,
                        3.141545370875028,
                        1.4277331959733954,
                        -385.0565011513918,
                        5967.300616082603
                    ]
                },
                "content": {
                    "uri": "0-1-0.json"
                }
            }
        ],
        "refine": "ADD"
    }
}

No response

@tdurand tdurand added the bug Something isn't working label Oct 18, 2024
@sraimund
Copy link

Yes, it looks like that the cullingVolume.computeVisibilityWithPlaneMask() function needs to be further examined.

As a workaround, the visibility can be checked by simply calculating 2D intersections between tiles and view bounding box. The dataset is displayed when changing the following lines of tile-3d.ts in updateVisibility():

this._visibilityPlaneMask = this.visibility(frameState, parentVisibilityPlaneMask);
this._visible = this._visibilityPlaneMask !== CullingVolume.MASK_OUTSIDE;

to

const bounds = frameState.viewport.getBounds();
this._visible = !(this.boundingBox[0][0] > bounds[0] && this.boundingBox[0][1] > bounds[1]
    && this.boundingBox[1][0] < bounds[2] && this.boundingBox[1][1] < bounds[3]);

grafik

@tdurand
Copy link
Author

tdurand commented Dec 14, 2024

thanks for this pointer 🤙🤙, will have a look !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants