1// Invented volumes, built through the lane's own types.2//3// The corpus (`testdata/corpus/bundles`) keeps two real volumes: bend-or, a4// plane city, and mars, a sphere. Two shapes of volume that used to be5// captured commercially are not in it any more, and the tests that proved6// them now prove them here instead, on volumes invented for the purpose:7//8// A SPLIT SHEET. One world pictured as horizontal bands, several lenses9// naming the same pyramid, each windowing its own band with `bounds` — and10// one of them declaring a `surface` smaller than its window, because the11// sheet drew a title in the margin. Every number is small enough to check12// by hand, which is the whole point of inventing it.13//14// A GAME PLANE. A city world whose district owns two separate pieces of15// ground (one with a hole in it) and whose canal is recorded as three16// runs — the multipart shapes — plus a lens bounded well inside the world17// square with margin on every side, and a hand-drawn lens that declares18// `interpolate: false`, the nearest-neighbour case no corpus lens carries.19//20// These are factories over `data/payload.ts` types and nothing else: a test21// that consumes one is exercising the same reader a real payload meets.2223import type { Collection, Lens, TileGrid, WorldPayload } from "../data/payload.ts";2425/** The world square every published bundle cuts: 8192 pixels, 256 to a tile. */26export const SQUARE: TileGrid = { sourceZoom: 13, firstTile: 4064, tileSize: 256, size: 8192 };2728/** One invented volume: its grid, and its worlds by slug. */29export interface SyntheticVolume {30 readonly slug: string;31 readonly tileGrid: TileGrid;32 readonly worlds: ReadonlyMap<string, WorldPayload>;33}3435const sheetLevels = (count: number) => Array.from({ length: count }, () => "webp");3637/**38 * The split sheet: three lenses, one pyramid, one band of the square each.39 *40 * The bands: Sky owns rows 0–2048, Land 2048–4096, Depths 4096–6144; the41 * bottom quarter of the square was never captured by anyone. Depths alone42 * goes a level past `fullZoom`, and its level-3 coverage admits exactly three43 * tiles — (0,4), (4,4) and (7,5) of the 8×2 tile band its window touches,44 * which is bits 0, 4 and 15 of a row-major bitset, low bit first: bytes45 * 0b00010001 and 0b10000000, base64 "EYA=".46 */47export function splitSheet(): SyntheticVolume {48 const shared = {49 tiles: "aerie-sheet",50 minZoom: 0,51 maxZoom: 2,52 fullZoom: 2,53 sourceZoom: 13,54 formats: sheetLevels(3),55 interpolate: true,56 };57 const lenses: Lens[] = [58 {59 ...shared,60 name: "Sky",61 bounds: { x: 0, y: 0, width: 8192, height: 2048 },62 // The window took in a title drawn beside the map; the ground is less.63 surface: { x: 512, y: 256, width: 7168, height: 1536 },64 },65 {66 ...shared,67 name: "Land",68 bounds: { x: 0, y: 2048, width: 8192, height: 2048 },69 },70 {71 ...shared,72 name: "Depths",73 maxZoom: 3,74 formats: sheetLevels(4),75 bounds: { x: 0, y: 4096, width: 8192, height: 2048 },76 coverage: { "3": { x: 0, y: 4, w: 8, h: 2, bits: "EYA=" } },77 },78 ];79 const world: WorldPayload = {80 lenses,81 collections: [],82 attrs: { "atlas.geometry.surface": "plane" },83 };84 return { slug: "aerie", tileGrid: SQUARE, worlds: new Map([["aloft", world]]) };85}8687/** A closed ring in the volume's own `[lng, lat]` space, as payloads spell it. */88function ring(lng: number, lat: number, span: number): number[][] {89 return [90 [lng, lat], [lng + span, lat], [lng + span, lat - span], [lng, lat - span], [lng, lat],91 ];92}9394/**95 * The game plane: one city world with the two multipart shapes that matter.96 *97 * "Twin Wards" is a MultiPolygon of two parts — the first carries a hole of98 * its own — so a builder that flattens rings onto one polygon turns the99 * second ward into a hole punched out of the first. "Old Canal" is a100 * MultiLineString of three runs, so a builder that keeps only the first run101 * silently drops two thirds of the water.102 */103export function gamePlane(): SyntheticVolume {104 const districts: Collection = {105 id: 1,106 title: "Districts",107 kind: "area",108 visible: true,109 features: [110 {111 id: 101,112 title: "Twin Wards",113 geometry: [{114 type: "MultiPolygon",115 coordinates: [116 [ring(-3, 44, 0.4), ring(-2.9, 43.9, 0.2)],117 [ring(-2, 44, 0.4)],118 ],119 }],120 },121 {122 id: 102,123 title: "Single Ward",124 geometry: [{ type: "Polygon", coordinates: [ring(-1, 44, 0.3)] }],125 },126 ],127 };128 const canals: Collection = {129 id: 2,130 title: "Canals",131 kind: "path",132 visible: true,133 features: [{134 id: 201,135 title: "Old Canal",136 geometry: [{137 type: "MultiLineString",138 coordinates: [139 [[-3, 44], [-2.8, 43.9], [-2.6, 44]],140 [[-2.5, 44], [-2.4, 43.95]],141 [[-2.3, 44], [-2.2, 43.9], [-2.1, 44], [-2, 43.95]],142 ],143 }],144 }],145 };146 const cityLevels = (count: number) => Array.from({ length: count }, () => "jpg");147 const lenses: Lens[] = [148 {149 // A pyramid filling a window well inside the square: real margin on150 // every side for an unclipped layer to draw into.151 name: "Streets",152 tiles: "old-quarter",153 minZoom: 0,154 maxZoom: 5,155 fullZoom: 5,156 sourceZoom: 13,157 formats: cityLevels(6),158 bounds: { x: 2016, y: 2020, width: 4159, height: 4378 },159 interpolate: true,160 },161 {162 // A surface and no bounds: the ground it pictures is declared, the163 // window is not, and the camera must fit the whole square. Pixel art,164 // so it resamples nearest-neighbour.165 name: "Hand-Drawn",166 tiles: "old-quarter-drawn",167 minZoom: 0,168 maxZoom: 4,169 fullZoom: 4,170 sourceZoom: 13,171 formats: cityLevels(5),172 surface: { x: 1563, y: 2000, width: 5066, height: 4191 },173 interpolate: false,174 },175 ];176 const world: WorldPayload = {177 lenses,178 collections: [districts, canals],179 attrs: { "atlas.geometry.surface": "plane" },180 };181 return { slug: "neon-harbor", tileGrid: SQUARE, worlds: new Map([["old-quarter", world]]) };182}