Description
When the map's zoom level exceeds a tile layer's configured maxZoom, the zoom hysteresis logic in TileManager.update() can override the clamped tileZoom value, causing tile requests at zoom levels beyond maxZoom.
Steps to reproduce
- Create a BitmapTileLayer with a tile source that has maxZoom = 7
- Set the map position to zoom level 8 or higher
- Observe that tile requests are made at zoom 8 instead of being clamped to 7
Root cause
In TileManager.update(), mPrevZoomlevel is initialized from the unclamped pos.zoomLevel:
if (mNewTiles == null || mNewTiles.tiles.length == 0) {
mPrevZoomlevel = pos.zoomLevel; // unclamped — can exceed mMaxZoom
init();
}
int tileZoom = clamp(pos.zoomLevel, mMinZoom, mMaxZoom); // correctly clamped
// Hysteresis logic:
int zoomDiff = tileZoom - mPrevZoomlevel; // e.g., 7 - 8 = -1
if (zoomDiff == -1) {
if (scaleDiv > mLevelDownThreshold) {
tileZoom = mPrevZoomlevel; // reverts to 8, bypassing maxZoom
}
}
mPrevZoomlevel = tileZoom; // persists the unclamped value
The hysteresis interprets the clamped-vs-unclamped difference as a "zoom out" and holds the previous (unclamped) zoom level. This persists on subsequent updates because mPrevZoomlevel remains above mMaxZoom.
Suggested fix
Clamp mPrevZoomlevel during initialization:
if (mNewTiles == null || mNewTiles.tiles.length == 0) {
mPrevZoomlevel = clamp(pos.zoomLevel, mMinZoom, mMaxZoom);
init();
}
Or apply the clamp after the hysteresis adjustment:
// after the threshold logic block:
tileZoom = clamp(tileZoom, mMinZoom, mMaxZoom);
mPrevZoomlevel = tileZoom;
Impact
Any BitmapTileLayer (or other tile layer) with a maxZoom lower than the map's current zoom level will request tiles beyond its configured maximum. This causes unnecessary HTTP requests to non-existent tile endpoints and potential rendering issues.
Description
When the map's zoom level exceeds a tile layer's configured
maxZoom, the zoom hysteresis logic inTileManager.update()can override the clamped tileZoom value, causing tile requests at zoom levels beyondmaxZoom.Steps to reproduce
Root cause
In
TileManager.update(),mPrevZoomlevelis initialized from the unclampedpos.zoomLevel:The hysteresis interprets the clamped-vs-unclamped difference as a "zoom out" and holds the previous (unclamped) zoom level. This persists on subsequent updates because mPrevZoomlevel remains above mMaxZoom.
Suggested fix
Clamp mPrevZoomlevel during initialization:
Or apply the clamp after the hysteresis adjustment:
Impact
Any BitmapTileLayer (or other tile layer) with a maxZoom lower than the map's current zoom level will request tiles beyond its configured maximum. This causes unnecessary HTTP requests to non-existent tile endpoints and potential rendering issues.