mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
fix(street-level): address gekh's review of #768
P0 - tileMath: lonToTileX(180) wrapped to column 0, so a whole-world view at z1 loaded only the western column; 180 is now the last column. - coverage.loadTile: a superseded request (after a retire or clear) still deleted the newer request's pending entry and loading count in `finally`, letting a duplicate load attach lines that nothing could remove. Only the request that still owns the key attaches its tile or settles the key. P1 - view/tileMath: a view across the date line read as a ~358 deg box and loaded tiles on the far side of the globe. visibleBbox now returns west > east for such views and tilesForBbox splits them at +/-180; viewCentre averages across the line. - decode: the parts of a multi-line sequence were joined into one line, drawing straight segments over capture gaps. Each part is now its own line (`parts`); later parts carry `~n` in their pick id, and picking or recolouring any part acts on the whole sequence. - viewerHost: a prewarmed MapillaryJS viewer was never destroyed, leaking its WebGL context. Prewarmed adapters are tracked and released on unmount, at once when the layer went off mid-load, and per provider when only that provider is switched off. - nearestImage took the first record the API returned; it now takes the closest one that passes the filter. P2 - groundCast: the cache was cleared after a request counted its corners, dropping ones it relied on; it is now cleared first. - streetLevelControls: the viewer was resized on every render (every frame while a panorama is dragged); the ResizeObserver handles size changes and the viewer is resized once when it opens. The legend now rebuilds when its entries change, not only their count. - panelPositionControls: the portable-panel paths this PR added called the CCTV viewport sync directly; they go through onPanelResized, which the shell routes to CCTV. The "Compose camera panel controls" JSDoc is back on _initCctvPanel. New tests: zoom-1 columns, date-line tiles and bbox, multi-part decode and part pick ids, nearest image, prewarmed viewer release, and the cache ordering (fails on the old order). Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
514788303d
commit
a1f8d6ca25
17 files changed
+435
-117
No files matched your search
@@ -12,6 +12,8 @@ function clampLat(lat) {
|
||||
/** Tile column for a longitude at zoom z. */
|
||||
export function lonToTileX(lon, z) {
|
||||
const n = 2 ** z;
|
||||
// 180° is the east edge of the last column, not the west edge of the first.
|
||||
if (lon >= 180) return n - 1;
|
||||
const wrapped = ((((lon + 180) % 360) + 360) % 360) - 180;
|
||||
return Math.min(n - 1, Math.max(0, Math.floor(((wrapped + 180) / 360) * n)));
|
||||
}
|
||||
@@ -91,13 +93,38 @@ export function countTilesForBbox(bbox, z) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerate the tiles at zoom z covering a bbox, ordered from the centre of
|
||||
* Enumerate the tiles at zoom z covering a bbox (west > east means it crosses
|
||||
* the date line), ordered from the centre of
|
||||
* the box outwards so a progressive renderer fills in what the user is most
|
||||
* likely looking at first. `limit` caps the list; the result reports whether
|
||||
* the cap was hit.
|
||||
* @returns {{tiles: Array<{x:number,y:number,z:number}>, truncated: boolean, total: number}}
|
||||
*/
|
||||
export function tilesForBbox(bbox, z, { limit = Infinity } = {}) {
|
||||
// A box across the date line comes as west > east: split it at ±180°.
|
||||
if (Array.isArray(bbox) && Number(bbox[0]) > Number(bbox[2])) {
|
||||
const [west, south, east, north] = bbox.map(Number);
|
||||
const n = 2 ** z;
|
||||
const tiles = [
|
||||
...tilesForBbox([west, south, 180, north], z).tiles,
|
||||
...tilesForBbox([-180, south, east, north], z).tiles,
|
||||
];
|
||||
const x0 = lonToTileX(west, z);
|
||||
const x1 = lonToTileX(east, z) + n;
|
||||
const cx = ((x0 + x1) / 2) % n;
|
||||
const cy = (latToTileY(north, z) + latToTileY(south, z)) / 2;
|
||||
const dx = (x) => Math.min(Math.abs(x - cx), n - Math.abs(x - cx));
|
||||
tiles.sort(
|
||||
(a, b) =>
|
||||
dx(a.x) ** 2 + (a.y - cy) ** 2 - (dx(b.x) ** 2 + (b.y - cy) ** 2),
|
||||
);
|
||||
const truncated = tiles.length > limit;
|
||||
return {
|
||||
tiles: truncated ? tiles.slice(0, limit) : tiles,
|
||||
truncated,
|
||||
total: tiles.length,
|
||||
};
|
||||
}
|
||||
const box = normalizeBbox(bbox);
|
||||
if (!box) return { tiles: [], truncated: false, total: 0 };
|
||||
const x0 = lonToTileX(box.west, z);
|
||||
|
||||
Reference in new issue
Block a user