mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
Merge branch 'main' into contrib/gods-015-imagery-box-missing-edge-20261011-reviewed
This commit is contained in:
commit
4a2c6ff7f6
4 files changed
+48
-2
No files matched your search
@@ -24,6 +24,9 @@
|
|||||||
the five borough cores load and `CCTV_NYC_MAX_SOURCES` changes the cap. The catalog-wide ceiling is
|
the five borough cores load and `CCTV_NYC_MAX_SOURCES` changes the cap. The catalog-wide ceiling is
|
||||||
unchanged; extra cameras share it round-robin with the other packs.
|
unchanged; extra cameras share it round-robin with the other packs.
|
||||||
|
|
||||||
|
- Street Level counts unique tiles before ranking so overlapping dateline halves
|
||||||
|
in polar views do not waste slots in the 16-tile overview budget.
|
||||||
|
|
||||||
- Directions no longer shows a truncation notice for a route with exactly 200
|
- Directions no longer shows a truncation notice for a route with exactly 200
|
||||||
turns, and a roundabout at the 200th turn keeps its exit distance.
|
turns, and a roundabout at the 200th turn keeps its exit distance.
|
||||||
|
|
||||||
|
|||||||
@@ -3132,6 +3132,10 @@ sequence lines below 60 km; the proxy strips the unused `image` layer from z14
|
|||||||
tiles (12 MB → ~80 KB) and shares one upstream fetch between concurrent
|
tiles (12 MB → ~80 KB) and shares one upstream fetch between concurrent
|
||||||
requests for a tile.
|
requests for a tile.
|
||||||
|
|
||||||
|
Mapillary coverage ranks unique tile addresses before applying the 16-tile
|
||||||
|
overview budget. Overlapping dateline halves in a polar view therefore do not
|
||||||
|
waste overview slots on the same tile; loading already skips duplicate keys.
|
||||||
|
|
||||||
On Google 3D (`photoreal`) at street zoom (in below 1,400 m above ground, out
|
On Google 3D (`photoreal`) at street zoom (in below 1,400 m above ground, out
|
||||||
above 1,800 m) the surface mode switches from `draped` to `terrain`: draped
|
above 1,800 m) the surface mode switches from `draped` to `terrain`: draped
|
||||||
lines land on roofs and tree tops, so `groundCast.js` instead places lines,
|
lines land on roofs and tree tops, so `groundCast.js` instead places lines,
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import { tilesForBbox } from './tileMath.js';
|
||||||
|
|
||||||
|
test('reachable polar dateline coverage ranks 24 distinct tiles before overview truncation', () => {
|
||||||
|
// coverage uses the actual view bbox above zoom 1; polar views can wrap.
|
||||||
|
const bbox = [-10, 60, -20, 85];
|
||||||
|
const result = tilesForBbox(bbox, 3);
|
||||||
|
const keys = result.tiles.map((tile) => `${tile.x}/${tile.y}/${tile.z}`);
|
||||||
|
assert.equal(keys.length, 24);
|
||||||
|
assert.equal(new Set(keys).size, 24);
|
||||||
|
assert.equal(result.total, 24);
|
||||||
|
assert.equal(result.truncated, false);
|
||||||
|
const overview = tilesForBbox(bbox, 3, { limit: 16 });
|
||||||
|
assert.equal(overview.total, 24);
|
||||||
|
assert.equal(overview.tiles.length, 16);
|
||||||
|
assert.equal(
|
||||||
|
new Set(overview.tiles.map((tile) => `${tile.x}/${tile.y}/${tile.z}`)).size,
|
||||||
|
16,
|
||||||
|
);
|
||||||
|
assert.equal(overview.truncated, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('a limit that fits every distinct tile is not spent on repeats', () => {
|
||||||
|
// Before de-duplication this box yielded 27 entries for 24 tiles, so a
|
||||||
|
// 24-slot overview held repeats and still reported itself truncated.
|
||||||
|
const result = tilesForBbox([-10, 60, -20, 85], 3, { limit: 24 });
|
||||||
|
const keys = result.tiles.map((tile) => `${tile.x}/${tile.y}/${tile.z}`);
|
||||||
|
assert.equal(new Set(keys).size, 24);
|
||||||
|
assert.equal(result.truncated, false);
|
||||||
|
});
|
||||||
@@ -146,8 +146,16 @@ export function tilesForBbox(bbox, z, { limit = Infinity, focus = null } = {}) {
|
|||||||
const dx = Math.abs(tile.x - centre.x);
|
const dx = Math.abs(tile.x - centre.x);
|
||||||
return Math.min(dx, n - dx) ** 2 + (tile.y - centre.y) ** 2;
|
return Math.min(dx, n - dx) ** 2 + (tile.y - centre.y) ** 2;
|
||||||
};
|
};
|
||||||
// Each tile's distance is computed once; ties keep their row order.
|
// The date-line halves share a column when the gap between east and west is
|
||||||
const ranked = tiles
|
// narrower than a tile; count that column once so a capped overview does not
|
||||||
|
// spend its slots on repeats. Each tile's distance is computed once; ties keep
|
||||||
|
// their row order.
|
||||||
|
const unique = [
|
||||||
|
...new Map(
|
||||||
|
tiles.map((tile) => [`${tile.x}/${tile.y}/${tile.z}`, tile]),
|
||||||
|
).values(),
|
||||||
|
];
|
||||||
|
const ranked = unique
|
||||||
.map((tile) => ({ tile, d: distance2(tile) }))
|
.map((tile) => ({ tile, d: distance2(tile) }))
|
||||||
.sort((a, b) => a.d - b.d)
|
.sort((a, b) => a.d - b.d)
|
||||||
.map(({ tile }) => tile);
|
.map(({ tile }) => tile);
|
||||||
|
|||||||
Reference in new issue
Block a user