maplibre / maplibre-gl-js

MapLibre GL JS - Interactive vector tile maps in the browser
https://maplibre.org/maplibre-gl-js/docs/
Other
6.33k stars 689 forks source link

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

Open ben-xD opened 5 months ago

ben-xD commented 5 months ago

maplibre-gl-js version: 4.1.2

browser:

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.

HarelM commented 5 months ago

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).

ben-xD commented 5 months ago

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.

https://github.com/maplibre/maplibre-gl-js/assets/24711048/fba24629-4454-4ee6-b2a0-05d1c60d0e0f

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

index.html ```html 3D Terrain
```
HarelM commented 5 months ago

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...