Atlaslog / Field Notes / Tiles
Field note · Tiles
Map repeats three times at zoom 3 because noWrap is off
Quick answer
At zoom 3 in a 1600 px container, three copies of China appear side by side and the outer copies are discontinuous. Leaflet wraps the world horizontally whenever 2^z multiplied by `tileSize` is narrower than the viewport.
Symptom
- Three copies of China appear at zoom 3 and five at zoom 2
- World width at z3 is 8 x 256 = 2048 px against a 1600 px container, so wrapping kicks in
- Repeated copies show the same tile or 404s because the service covers only China
Checklist
- Compute `2^z * tileSize` and compare it with the container width
- Check the `noWrap` option, which defaults to `false`
- Check whether `bounds` or `maxBounds` is set
- Check whether `minZoom` is below the service's real minimum of 3 or 4
- Reproduce at zoom 2 and 3 and count the repeats
Fix
Set `noWrap: true` with `minZoom: 4` and `bounds: [[3.5, 73.0], [53.6, 135.1]]`, and constrain the map with `maxBounds` plus `maxBoundsViscosity: 0.8`; in OpenLayers set `wrapX: false` on the XYZ source.
Code
const worldWidth = Math.pow(2, map.getZoom()) * 256;
console.log(worldWidth, map.getSize().x);
// 2 级: 1024 vs 1600 -> 世界比视口窄,必然重复L.tileLayer('https://tile.example.com/{z}/{x}/{y}.png', {
minZoom: 4,
maxZoom: 18,
noWrap: true,
bounds: [[3.5, 73.0], [53.6, 135.1]] // 中国范围
}).addTo(map);
const map = L.map('map', {
minZoom: 4,
maxBounds: [[3.5, 73.0], [53.6, 135.1]],
maxBoundsViscosity: 0.8
});
Watch out
- Setting only `noWrap` without raising `minZoom`, so zoom 2 still shows a world narrower than the viewport with broken edges
- Using `maxBounds` alone with a low `minZoom`, which still lets the viewport pull repeated tiles into view
English edition written for Atlaslog from the original Chinese field note. Code is unchanged and runs as-is.
Atlaslog (2026). Map repeats three times at zoom 3 because noWrap is off. https://www.jingweizhi.com/en/cookbook/tile-nowrap-out-of-range.html (accessed 2026-11-03).