import assert from "node:assert/strict"; import { readFile } from "node:fs/promises"; import test from "node:test"; import { DEFAULT_GRID_LOD_PROFILES, gridLodProfile, gridShouldBeVisible, resolveGridMode, selectGridLod, snapGridCenter, } from "../apps/catalog/src/mapGridPolicy.mjs"; const settings = { gridVisible: true, gridLodEnabled: true, grid3dEnabled: true, gridGraticuleEnabled: true, gridAutoDisableHeightKm: 10_000, gridCenterMode: "fixed", gridCenterLatitude: 55.7558, gridCenterLongitude: 37.6173, gridLodProfiles: DEFAULT_GRID_LOD_PROFILES, }; test("canonical defaults preserve the exact effective MMAP/MOSCOWMAP five-LOD donor profile", () => { assert.deepEqual(DEFAULT_GRID_LOD_PROFILES, [ { maxHeightKm: 10, stepKm: 1, mode: "3d", heightMeters: 300, max3dViewAngleDegrees: 30, tileSizeKm: 10, radiusKm: 50, lineDiameterMeters: 4, lineColor: "#f5f5f5", lineOpacity: 12, dotsEnabled: true, dotsDiameterMeters: 7, dotsColor: "#ffffff", dotsOpacity: 58, crossesEnabled: false, crossesLengthMeters: 60, crossesWidthMeters: 10, crossesColor: "#9c9c9c", crossesOpacity: 46, graticuleStepDegrees: 0.25, graticuleLineWidthPx: 1, graticuleColor: "#f5f5f5", graticuleOpacity: 12, }, { maxHeightKm: 50, stepKm: 5, mode: "3d", heightMeters: 500, max3dViewAngleDegrees: 30, tileSizeKm: 10, radiusKm: 1_000, lineDiameterMeters: 10, lineColor: "#f8fbfc", lineOpacity: 12, dotsEnabled: true, dotsDiameterMeters: 80, dotsColor: "#ffffff", dotsOpacity: 22, crossesEnabled: false, crossesLengthMeters: 60, crossesWidthMeters: 10, crossesColor: "#9c9c9c", crossesOpacity: 46, graticuleStepDegrees: 0.5, graticuleLineWidthPx: 1, graticuleColor: "#f8fbfc", graticuleOpacity: 12, }, { maxHeightKm: 200, stepKm: 25, mode: "3d", heightMeters: 500, max3dViewAngleDegrees: 30, tileSizeKm: 25, radiusKm: 1_000, lineDiameterMeters: 7, lineColor: "#fafafa", lineOpacity: 12, dotsEnabled: true, dotsDiameterMeters: 10, dotsColor: "#ffffff", dotsOpacity: 58, crossesEnabled: false, crossesLengthMeters: 60, crossesWidthMeters: 10, crossesColor: "#9c9c9c", crossesOpacity: 46, graticuleStepDegrees: 1, graticuleLineWidthPx: 1, graticuleColor: "#fafafa", graticuleOpacity: 12, }, { maxHeightKm: 800, stepKm: 50, mode: "graticule", heightMeters: 500, max3dViewAngleDegrees: 30, tileSizeKm: 10, radiusKm: 1_000, lineDiameterMeters: 10, lineColor: "#fcfdfd", lineOpacity: 12, dotsEnabled: true, dotsDiameterMeters: 10, dotsColor: "#fcfdfd", dotsOpacity: 58, crossesEnabled: false, crossesLengthMeters: 60, crossesWidthMeters: 10, crossesColor: "#9c9c9c", crossesOpacity: 46, graticuleStepDegrees: 2, graticuleLineWidthPx: 1, graticuleColor: "#fcfdfd", graticuleOpacity: 12, }, { maxHeightKm: 3_000, stepKm: 50, mode: "graticule", heightMeters: 500, max3dViewAngleDegrees: 30, tileSizeKm: 10, radiusKm: 100, lineDiameterMeters: 7, lineColor: "#9c9c9c", lineOpacity: 12, dotsEnabled: true, dotsDiameterMeters: 10, dotsColor: "#9c9c9c", dotsOpacity: 58, crossesEnabled: false, crossesLengthMeters: 60, crossesWidthMeters: 10, crossesColor: "#9c9c9c", crossesOpacity: 46, graticuleStepDegrees: 2, graticuleLineWidthPx: 1, graticuleColor: "#9c9c9c", graticuleOpacity: 8, }, ]); }); test("LOD selection keeps three spatial bands, two graticule bands and the independent 10,000 km cutoff", () => { assert.deepEqual( [0, 10, 10.001, 50, 50.001, 200, 200.001, 800, 800.001, 3_000, 9_999].map((height) => { const band = selectGridLod(settings, height); return [band.id, band.stepKm, band.mode]; }), [ ["lod-1", 1, "3d"], ["lod-1", 1, "3d"], ["lod-2", 5, "3d"], ["lod-2", 5, "3d"], ["lod-3", 25, "3d"], ["lod-3", 25, "3d"], ["lod-4", 50, "graticule"], ["lod-4", 50, "graticule"], ["lod-5", 50, "graticule"], ["lod-5", 50, "graticule"], ["lod-5", 50, "graticule"], ], ); assert.equal(gridShouldBeVisible(settings, 10_000), true); assert.equal(gridShouldBeVisible(settings, 10_000.001), false); }); test("every LOD owns independent metric and angular spacing and visual fields", () => { const profiles = DEFAULT_GRID_LOD_PROFILES.map((profile, index) => ({ ...profile, stepKm: 11 + index, lineDiameterMeters: 21 + index, graticuleStepDegrees: 0.125 * (index + 1), graticuleLineWidthPx: 1 + (index % 3), graticuleColor: `#00000${index}`, graticuleOpacity: 30 + index, })); const profile = gridLodProfile({ ...settings, gridLodProfiles: profiles }, 3); assert.equal(profile.stepKm, 14); assert.equal(profile.lineDiameterMeters, 24); assert.equal(profile.graticuleStepDegrees, 0.5); assert.equal(profile.graticuleLineWidthPx, 1); assert.equal(profile.graticuleColor, "#000003"); assert.equal(profile.graticuleOpacity, 33); }); test("legacy flat visuals migrate while angular graticule spacing stays independent", () => { const profile = gridLodProfile({ ...settings, gridLodProfiles: undefined, gridRadiusKm: 1_234, gridHeightMeters: 640, gridLineDiameterMeters: 17, gridColor: "#abcdef", gridOpacity: 37, gridDotsEnabled: false, gridLod2StepKm: 7, }, 1); assert.equal(profile.maxHeightKm, 50); assert.equal(profile.stepKm, 7); assert.equal(profile.radiusKm, 1_234); assert.equal(profile.heightMeters, 640); assert.equal(profile.lineDiameterMeters, 17); assert.equal(profile.lineColor, "#abcdef"); assert.equal(profile.lineOpacity, 37); assert.equal(profile.dotsEnabled, false); assert.equal(profile.graticuleStepDegrees, 0.5); assert.equal(profile.graticuleLineWidthPx, 1); assert.equal(profile.graticuleColor, "#abcdef"); assert.equal(profile.graticuleOpacity, 37); }); test("LOD hysteresis holds the previous band for eight percent on either side of a threshold", () => { assert.equal(selectGridLod(settings, 10.8, 0).id, "lod-1"); assert.equal(selectGridLod(settings, 10.8001, 0).id, "lod-2"); assert.equal(selectGridLod(settings, 9.2001, 1).id, "lod-2"); assert.equal(selectGridLod(settings, 9.1999, 1).id, "lod-1"); assert.equal(selectGridLod(settings, 864, 3).id, "lod-4"); assert.equal(selectGridLod(settings, 864.001, 3).id, "lod-5"); }); test("mode fallback preserves a usable grid when one renderer is disabled", () => { assert.equal(resolveGridMode(settings, "3d"), "3d"); assert.equal(resolveGridMode(settings, "graticule"), "graticule"); assert.equal(resolveGridMode({ ...settings, grid3dEnabled: false }, "3d"), "graticule"); assert.equal(resolveGridMode({ ...settings, gridGraticuleEnabled: false }, "graticule"), "3d"); assert.equal(resolveGridMode({ ...settings, grid3dEnabled: false, gridGraticuleEnabled: false }, "3d"), "hidden"); }); test("grid center is fixed and camera-independent, including for legacy camera-mode payloads", () => { const first = snapGridCenter({ latitude: 55.7558, longitude: 37.6173 }, settings); const second = snapGridCenter({ latitude: -22, longitude: -140 }, settings); assert.deepEqual(first, { latitude: 55.7558, longitude: 37.6173 }); assert.deepEqual(second, first); assert.deepEqual(snapGridCenter({ latitude: 0, longitude: 0 }, { ...settings, gridCenterMode: "camera", gridCenterLatitude: 12.5, gridCenterLongitude: 190, }), { latitude: 12.5, longitude: -170 }); }); test("renderer uses fixed ENU sectors, angular graticules and a non-blank double-buffer swap", async () => { const source = await readFile(new URL("../apps/catalog/src/CesiumMapRenderer.tsx", import.meta.url), "utf8"); assert.match(source, /class GridLayerController/); assert.match(source, /dataSourceDisplay\.ready/); assert.match(source, /fixedGridOrigin\(presentation\)/); assert.match(source, /Transforms\.eastNorthUpToFixedFrame\(anchor\)/); assert.match(source, /localSectorAt\(/); assert.match(source, /gridController\?\.pick\(worldPosition\)/); assert.match(source, /lod\.stepKm \* 1_000/); assert.match(source, /lod\.graticuleStepDegrees/); assert.match(source, /lod\.graticuleLineWidthPx/); assert.match(source, /arcType: ArcType\.RHUMB/); assert.match(source, /clampToGround: false/); assert.match(source, /mountResources\(resources\)[\s\S]*?const previous = this\.current;[\s\S]*?removeResources\(previous\.resources\)/); assert.doesNotMatch(source, /function rebuildElevatedGrid[\s\S]*?entities\.removeAll\(\)/); assert.doesNotMatch(source, /Math\.min\(40,[\s\S]*?safeRadiusKm \/ safeStepKm/); assert.doesNotMatch(source, /snapGridCenter\(/); });