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

App using terrain (raster-dem) crashes when zooming out after zooming in quickly #3982

Open
ben-xD opened this issue Apr 11, 2024 · 3 comments
Labels
bug Something isn't working PR is more than welcomed Extra attention is needed Terrain 3D

Comments

@ben-xD
Copy link

ben-xD commented Apr 11, 2024

maplibre-gl-js version: 4.1.2

browser:

  • Firefox 124.0.2 (64-bit)
  • Chrome Version 123.0.6312.107 (Official Build) (arm64)

Overview

I've got an app that uses terrain (raster-dem) as following https://maplibre.org/maplibre-gl-js/docs/examples/3d-terrain/, but it consistently crashes when zooming out after zooming in quickly. It has different errors depending on the browser.

On Firefox, crashes with

TypeError: this._tiles[T] is undefined
    update https://geojsons.com/assets/maplibre-gl-Cb84O7q2.js:5
    _updateSources https://geojsons.com/assets/maplibre-gl-Cb84O7q2.js:5
    _render https://geojsons.com/assets/maplibre-gl-Cb84O7q2.js:580
    _render https://geojsons.com/assets/index-DPuhvsxQ.js:40
    redraw https://geojsons.com/assets/index-DPuhvsxQ.js:40
    setProps https://geojsons.com/assets/index-DPuhvsxQ.js:40
    nue https://geojsons.com/assets/index-DPuhvsxQ.js:40
    gT https://geojsons.com/assets/index-DPuhvsxQ.js:40
    d6 https://geojsons.com/assets/index-DPuhvsxQ.js:40
    EX https://geojsons.com/assets/index-DPuhvsxQ.js:40
    wle https://geojsons.com/assets/index-DPuhvsxQ.js:40

On Chrome, crashes with:

index-DPuhvsxQ.js:40 TypeError: Cannot read properties of undefined (reading 'clearFadeHold')
    at Wt.update (maplibre-gl-Cb84O7q2.js:5:316045)
    at Ci._updateSources (maplibre-gl-Cb84O7q2.js:5:378798)
    at k.Map._render (maplibre-gl-Cb84O7q2.js:580:203711)
    at s._render (index-DPuhvsxQ.js:40:64095)
    at jA.redraw (index-DPuhvsxQ.js:40:64985)
    at jA.setProps (index-DPuhvsxQ.js:40:62928)
    at index-DPuhvsxQ.js:40:70798
    at gT (index-DPuhvsxQ.js:40:24296)
    at d6 (index-DPuhvsxQ.js:40:31641)
    at EX (index-DPuhvsxQ.js:40:31497)

I tried to create a reproducible example with example in https://maplibre.org/maplibre-gl-js/docs/examples/3d-terrain/, but I found a slightly different issue. I just created an index.html containing the HTML snippet, and replaced the url for terrainSource and hillshadeSource with https://api.maptiler.com/tiles/terrain-rgb/tiles.json?key=MY_KEY_FROM_MAPTILER. Zooming in/out in that one will crash with:

Uncaught Error: Invalid LngLat object: (NaN, NaN)
    Gu lng_lat.ts:63
    toLngLat mercator_coordinate.ts:126
    coordinateLocation transform.ts:584
    pointLocation transform.ts:565
    unproject map.ts:1166
    Es events.ts:527
    mousemove map_event.ts:122
    handleEvent handler_manager.ts:391
    addEventListener dom.ts:62
    _a handler_manager.ts:209
    <anonymous> map.ts:633
    <anonymous> index.html:18

Steps to Trigger Behavior

  1. Zoom in quickly, then
  2. Zoom out quickly

There are other ways to reproduce this, like programmatically setting the view state to a high zoom, and them zooming out. But the simplest

It seems like zooming in quickly, or programmatically will be too quick for maplibre to download all the terrain data. It then crashes when zooming out, and can't find it.

Link to Demonstration

Just zoom in and out quickly on https://geojsons.com/. Commenting out https://github.com/ben-xD/geojsons/blob/6f13536abb8e52beb9bded1095501cefc4d13220/frontend/src/map/GeojsonsMap.tsx#L352-L358 will fix the crashing. It seems like using raster-dem / terrain causes this issue.

Expected Behavior

No crashing. Zoom in/out works.

Actual Behavior

App crashes when zooming out.

if anyone could suggest a workaround or a fix, I would be grateful. Thanks

Workaround

Disable terrain completely.

@ben-xD ben-xD changed the title App using terrain (raster-dem) crashes with Cannot read properties of undefined when zooming out after zooming in quickly App using terrain (raster-dem) crashes when zooming out after zooming in quickly Apr 12, 2024
@HarelM
Copy link
Member

HarelM commented Apr 12, 2024

I can't reproduce this when using the example page on a macos with chrome:
https://maplibre.org/maplibre-gl-js/docs/examples/3d-terrain/

Can you try and create a jsbin that reproduces this?
Since geojsons.com might have some wrapper library that can cause issues I prefer to have a jsbin without any wrappers that reproduces this issue.
It's also worth trying to see if you can find a version that this bug doesn't happen in, so we can maybe find the relevant PR that caused this issue (assuming it was there from the initial introduction of the terrain code).

@HarelM HarelM added the need more info Further information is requested label Apr 12, 2024
@ben-xD
Copy link
Author

ben-xD commented Apr 16, 2024

Hey @harel,

I'll investigate further on the first error (TypeError: this._tiles[T] is undefined) which impacts me and happens almost instantly when i zoom in/out quickly. I'll try create a reproducible example.

However, for the demo crashing, did you try a non-demo terrain url? I was able to reproduce the error using maplibre.org/maplibre-gl-js/docs/examples/3d-terrain, as long as I used maptiler's tiles. Or just update MY_KEY_FROM_MAPTILER in https://jsbin.com/romekiriho/1/edit?html,output to be your free Maptiler API key.

Here's a 15s video that is 2x speed of me just zooming in and out, and eventually the app crashes. So it took about 30 seconds, less problematic that the original error.

30-2x.mp4

I've also attached the html file, just update MY_KEY_FROM_MAPTILER

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <title>3D Terrain</title>
    <meta property="og:description" content="Go beyond hillshade and show elevation in actual 3D." />
    <meta charset='utf-8'>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel='stylesheet' href='https://unpkg.com/maplibre-gl@4.1.2/dist/maplibre-gl.css' />
    <script src='https://unpkg.com/maplibre-gl@4.1.2/dist/maplibre-gl.js'></script>
    <style>
        body { margin: 0; padding: 0; }
        html, body, #map { height: 100%; }
    </style>
</head>
<body>
<div id="map"></div>
<script>
    const key = "MY_KEY_FROM_MAPTILER"
    const map = (window.map = new maplibregl.Map({
        container: 'map',
        zoom: 12,
        center: [11.39085, 47.27574],
        pitch: 52,
        hash: true,
        style: {
            version: 8,
            sources: {
                osm: {
                    type: 'raster',
                    tiles: ['https://a.tile.openstreetmap.org/{z}/{x}/{y}.png'],
                    tileSize: 256,
                    attribution: '&copy; OpenStreetMap Contributors',
                    maxzoom: 19
                },
                // Use a different source for terrain and hillshade layers, to improve render quality
                terrainSource: {
                    type: 'raster-dem',
                    url: `https://api.maptiler.com/tiles/terrain-rgb/tiles.json?key=${key}`,
                    tileSize: 256
                },
                hillshadeSource: {
                    type: 'raster-dem',
                    url: `https://api.maptiler.com/tiles/terrain-rgb/tiles.json?key=${key}`,
                    tileSize: 256
                }
            },
            layers: [
                {
                    id: 'osm',
                    type: 'raster',
                    source: 'osm'
                },
                {
                    id: 'hills',
                    type: 'hillshade',
                    source: 'hillshadeSource',
                    layout: {visibility: 'visible'},
                    paint: {'hillshade-shadow-color': '#473B24'}
                }
            ],
            terrain: {
                source: 'terrainSource',
                exaggeration: 1
            }
        },
        maxZoom: 18,
        maxPitch: 85
    }));

    map.addControl(
        new maplibregl.NavigationControl({
            visualizePitch: true,
            showZoom: true,
            showCompass: true
        })
    );

    map.addControl(
        new maplibregl.TerrainControl({
            source: 'terrainSource',
            exaggeration: 1
        })
    );
</script>
</body>
</html>

@HarelM
Copy link
Member

HarelM commented Apr 16, 2024

The error in the console seems related to matrix inversion if I understand correctly.
I'm no linear algebra expert, but it might be some edge case related to the projection matrix.
I would try and find an easy way to reproduce this, otherwise, you'll have a hard time understanding what causes this.
I'm not able to reproduce it using the terrain 3D demo example page unfortunately...

@HarelM HarelM added bug Something isn't working PR is more than welcomed Extra attention is needed Terrain 3D and removed need more info Further information is requested labels Apr 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working PR is more than welcomed Extra attention is needed Terrain 3D
Projects
None yet
Development

No branches or pull requests

2 participants