-
Notifications
You must be signed in to change notification settings - Fork 98
Description
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 valueThe 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.