-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
fix recursive dem tiles loading for 404s #11276
Conversation
Tests are failing because also, the terrain is wiggling terrain-wiggling.mov |
Other than failing tests, this looks good. Is there anything we can do further to make this less brittle? If we wanted to refactor and remove the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is useful to evaluate what happens (what tile requests are made) when displaying sea view. In such case, 404s are used for tiles away from land.
src/source/source_cache.js
Outdated
@@ -241,14 +241,14 @@ class SourceCache extends Evented { | |||
tile.state = 'errored'; | |||
if ((err: any).status !== 404) this._source.fire(new ErrorEvent(err, {tile})); | |||
// continue to try loading parent/children tiles if a tile doesn't exist (404) | |||
else this.update(this.transform); | |||
else this.update(this.transform, undefined, this._source.type === 'raster-dem'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is good to evaluate what happens when when raster dem source is not used for terrain, but only for hillshade. userForTerrain property gets evaluated to true here.
Otherwise, when used for terrain, we need to cache tile size for this source supplied (it is scaled up in code below) and if in consecutive update here we end up requesting tile cover with different tile size. This is apparently the issue that existed before but now with sparse dem tile set the behavior is different.
mapbox-gl-js/src/terrain/terrain.js
Line 281 in cd46ea1
this.sourceCache.update(transform, demScale * proxyTileSize, true); |
8e2a695
to
5657f9d
Compare
The test is initiating tiles requests on the 14th zoom level and blocks tiles requests for zoom levels below 12 at the same time. mapbox-gl-js/test/unit/source/source_cache.test.js Lines 1784 to 1791 in 5657f9d
Without the fix, t.deepEqual(sourceCache.getRenderableIds(), []);
t.deepEqual(sourceCache.getIds(), [
new OverscaledTileID(14, 0, 14, 8192, 8192).key,
new OverscaledTileID(14, 0, 14, 8191, 8192).key,
new OverscaledTileID(14, 0, 14, 8192, 8191).key,
new OverscaledTileID(14, 0, 14, 8191, 8191).key,
]); After the fix, t.deepEqual(sourceCache.getRenderableIds(), [
new OverscaledTileID(12, 0, 12, 2048, 2048).key,
new OverscaledTileID(12, 0, 12, 2047, 2048).key,
new OverscaledTileID(12, 0, 12, 2048, 2047).key,
new OverscaledTileID(12, 0, 12, 2047, 2047).key,
]);
t.deepEqual(sourceCache.getIds(), [
new OverscaledTileID(12, 0, 12, 2048, 2048).key,
new OverscaledTileID(12, 0, 12, 2047, 2048).key,
new OverscaledTileID(12, 0, 12, 2048, 2047).key,
new OverscaledTileID(12, 0, 12, 2047, 2047).key,
new OverscaledTileID(13, 0, 13, 4096, 4096).key,
new OverscaledTileID(13, 0, 13, 4095, 4096).key,
new OverscaledTileID(13, 0, 13, 4096, 4095).key,
new OverscaledTileID(13, 0, 13, 4095, 4095).key,
new OverscaledTileID(14, 0, 14, 8192, 8192).key,
new OverscaledTileID(14, 0, 14, 8191, 8192).key,
new OverscaledTileID(14, 0, 14, 8192, 8191).key,
new OverscaledTileID(14, 0, 14, 8191, 8191).key,
]); |
There are some failing tests. The other one is Here is the video of the Before cut-before.movAfter cut-after.movI've updated the |
|
||
eventedParent.on('data', (e) => { | ||
if (e.dataType === 'source' && e.sourceDataType === 'metadata') { | ||
sourceCache.update(transform, undefined, sourceCache.usedForTerrain); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
undefined for tileSize is a bit problematic as it doesn't verify real case:
mapbox-gl-js/src/terrain/terrain.js
Lines 282 to 283 in 941ba0f
// As a result of update, we get new set of tiles: reset lookup cache. | |
this._findCoveringTileCache[this.sourceCache.id] = {}; |
I'd suggest to use transform.zoom = 16, tileSize of 4 * 512
and DEM source maxZoom of 10.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've created a separate test for the terrain
mapbox-gl-js/test/unit/terrain/terrain.test.js
Lines 1547 to 1605 in 7565093
test('terrain recursively loads parent tiles on 404', (t) => { | |
t.plan(2); | |
const style = createStyle(); | |
const map = createMap(t, {style, center: [0, 0], zoom: 16}); | |
map.once('style.load', () => { | |
map.addSource('mapbox-dem', { | |
'type': 'raster-dem', | |
'tiles': ['http://example.com/{z}/{x}/{y}.png'], | |
'tileSize': TILE_SIZE, | |
'maxzoom': 14 | |
}); | |
const cache = map.style._getSourceCache('mapbox-dem'); | |
cache.used = cache._sourceLoaded = true; | |
cache._loadTile = (tile, callback) => { | |
if (tile.tileID.canonical.z > 10) { | |
setTimeout(() => callback({status: 404}), 0); | |
} else { | |
tile.state = 'loaded'; | |
callback(null); | |
} | |
}; | |
map.setTerrain({'source': 'mapbox-dem'}); | |
map.once('idle', () => { | |
t.deepEqual(cache.getRenderableIds(), [ | |
new OverscaledTileID(10, 0, 10, 512, 512).key, | |
new OverscaledTileID(10, 0, 10, 511, 512).key, | |
new OverscaledTileID(10, 0, 10, 512, 511).key, | |
new OverscaledTileID(10, 0, 10, 511, 511).key, | |
], 'contains first renderable tiles'); | |
t.deepEqual(cache.getIds(), [ | |
new OverscaledTileID(10, 0, 10, 512, 512).key, | |
new OverscaledTileID(10, 0, 10, 511, 512).key, | |
new OverscaledTileID(10, 0, 10, 512, 511).key, | |
new OverscaledTileID(10, 0, 10, 511, 511).key, | |
new OverscaledTileID(11, 0, 11, 1024, 1024).key, | |
new OverscaledTileID(11, 0, 11, 1023, 1024).key, | |
new OverscaledTileID(11, 0, 11, 1024, 1023).key, | |
new OverscaledTileID(11, 0, 11, 1023, 1023).key, | |
new OverscaledTileID(12, 0, 12, 2048, 2048).key, | |
new OverscaledTileID(12, 0, 12, 2047, 2048).key, | |
new OverscaledTileID(12, 0, 12, 2048, 2047).key, | |
new OverscaledTileID(12, 0, 12, 2047, 2047).key, | |
new OverscaledTileID(13, 0, 13, 4096, 4096).key, | |
new OverscaledTileID(13, 0, 13, 4095, 4096).key, | |
new OverscaledTileID(13, 0, 13, 4096, 4095).key, | |
new OverscaledTileID(13, 0, 13, 4095, 4095).key, | |
new OverscaledTileID(14, 0, 14, 8192, 8192).key, | |
new OverscaledTileID(14, 0, 14, 8191, 8192).key, | |
new OverscaledTileID(14, 0, 14, 8192, 8191).key, | |
new OverscaledTileID(14, 0, 14, 8191, 8191).key, | |
], 'recursively loads parent tiles if current tiles not found'); | |
}); | |
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
Launch Checklist
This PR fixes recursive dem tiles loading according to #11161
mapbox-gl-js
changelog:<changelog>fix recursive dem tiles loading for 404s</changelog>
Before
before-dem-fix.mov
After
after-dem-fix.mov