// coverage.mjs — at a common screen size, full-detail tiles cover (nearly) the whole map area, also at high latitude export const viewport = { width: 1920, height: 1080 }; const cover = `const a = window.mapViewer; for (let i = 0; i < 80; i++) { await new Promise(r => setTimeout(r, 500)); const t = a.view.tiles; if (i > 2 && t.inflight === 0 && t.queue.length === 0) break; } const t = a.view.tiles, w = a.el.clientWidth - 360, h = a.el.clientHeight; let hit = 0, n = 0; const S = Math.PI / 180, span = 180 / 2 ** t.z; for (let i = 0; i < 30; i++) for (let j = 0; j < 40; j++) { const p = a.view.pick((j + 0.5) / 40 * w, (i + 0.5) / 30 * h); if (!p) continue; n++; const x = ((Math.floor((p.lon + 180) / span) % (2 * 2 ** t.z)) + 2 * 2 ** t.z) % (2 * 2 ** t.z), y = Math.min(2 ** t.z - 1, Math.floor((90 - p.lat) / span)); const e = t.tiles.get(t.z + '/' + x + '/' + y); if (e && e.state === 'ready' && e.mesh.visible) hit++; } return { z: t.z, share: +(hit / n).toFixed(3), tiles: t.tiles.size };`; const at = (lat, lon, alt) => `window.mapViewer.view.setState({ lat: ${lat}, lon: ${lon}, alt: ${alt} });`; export const steps = [ { name: '2 km view at 41°N: ≥ 90% full detail', wait: 5000, js: at(41, 3.5, 0.0006) + cover, expect: v => v.share >= 0.9 }, { name: '50 km view at 70°N: ≥ 90% full detail', js: at(70, 20, 0.006) + cover, expect: v => v.share >= 0.9 }, { name: '20 km view at 85°N: ≥ 90% full detail', js: at(85, 20, 0.003) + cover, expect: v => v.share >= 0.9 }, ];