Files
2026-05-27 23:29:53 +01:00

76 lines
5.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Tasks: enterprise-heightmap-tiles
**Change ID**: enterprise-heightmap-tiles
**Package**: `@suaveplan/heightmap-tiles`
**Target path**: `universal/geo/heightmap-tiles`
**Prerequisite packages on Verdaccio**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/geo`, `@suaveplan/serialize`
---
## 0. Pre-flight (non-negotiable)
- [ ] 0.1 Confirm clean working tree (`git status` reports nothing) and no in-flight worktrees with uncommitted work (`git worktree list` then `git status` in each)
- [ ] 0.2 If any worktrees exist under `.claude/worktrees/`, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (`git worktree remove`) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
- [ ] 0.3 Confirm the package set in `MANIFEST.md` matches `find packages -maxdepth 3 -name package.json` count. Drift here means a prior change archived without regenerating the manifest.
## 1. Scaffold
- [ ] Create `universal/geo/heightmap-tiles/` with `src/`, `tests/`, `src/__benchmarks__/` and all feature subdirectories per the layout in `proposal.md`.
- [ ] Write `package.json` at version `0.1.0` with `"type": "module"`, `"sideEffects": false`, correct `exports` map, `dependencies`, and `devDependencies`.
- [ ] Write `tsconfig.json` extending `@suaveplan/typescript-config/library.json`.
- [ ] Write `vitest.config.ts` using `createTestConfig()` from `@suaveplan/testing/config`.
- [ ] Add `lint`, `typecheck`, `test`, `test:coverage`, `build`, `docs:check` scripts.
---
## 2. Types + errors
- [ ] `src/types/common.ts` — `TileCoord`, `BitDepth`, `HeightmapTile`, `ElevationResult`, `EncodeOptions`, `PyramidBuilderOptions`, `BuildLevelOptions`, `HeightmapTileStore` (interface), `ContourLine`.
- [ ] `src/types/common.md` (≥200 words, both examples, API reference).
- [ ] `src/error-codes.ts` — `HeightmapErrorCode` (6 codes), metadata, register, eager call.
- [ ] `src/types/schemas.ts` + `schemas.md` — Zod schemas.
---
## 3. Core modules
- [ ] **`src/coords/tile-coords/`** — `latLngToTileCoord`, `tileCoordToBoundingBox`, `tileCoordToLatLng`, `tilesInBoundingBox`, `tileParent`, `tileChildren`. Tests: known lat/lng → tile at zoom 10, bounding box round-trip, parent/children consistency at multiple zoom levels, `tilesInBoundingBox` returns correct count for small area.
- [ ] **`src/codec/delta-codec/`** — `deltaEncode(tile): HeightmapTile`: converts raw int16/int8 tile to delta-encoded (each cell = cell - previous); first cell = cell value. `deltaDecode(tile): HeightmapTile`: inverse. Both are lossless for int16/int8. Tests: encode/decode round-trip for flat tile (all zeros), random int16 array, verify delta values are smaller in magnitude for smooth terrain.
- [ ] **`src/codec/tile-codec/`** — `encodeTile(tile, options?): Uint8Array`: serialises header (coord, dimensions, bitDepth, min/maxElevation, encoding) then data via `@suaveplan/serialize` MessagePack profile. `decodeTile(data): HeightmapTile`. Tests: encode/decode round-trip for 256×256 uint16 tile, float32 tile, bit depth selection.
- [ ] **`src/store/memory-store/`** — `createMemoryTileStore(): HeightmapTileStore`: `get`/`put`/`delete`/`list` backed by a `Map<string, HeightmapTile>` (key = `z/x/y`). Tests: CRUD, list by zoom, list with bounding box filter.
- [ ] **`src/pyramid/pyramid-builder/`** — `TilePyramidBuilder(store, options)`: `addSourceTile(tile)`: stores at natural zoom; `buildLevel(zoom)`: for each tile at `zoom+1`, generates parent by bilinear down-sampling the 4 children (or nearest available); `buildAll(minZoom, maxZoom)`. Tests: single source tile at zoom 12 → can build zoom 11 and 10; bilinear average matches expected value for flat 4-cell grid.
- [ ] **`src/elevation/elevation-lookup/`** — `lookupElevation(store, lat, lng, zoom?)`: fetches tile at computed coord + 3 neighbours; bilinear interpolation from 4 nearest pixels. Returns `ElevationResult`. Tests: exact pixel hit → `confidence: 'exact'`, between pixels → `confidence: 'interpolated'`, no tile → `elevation: NaN`.
- [ ] **`src/elevation/contour-extractor/`** — `extractContours(tile, intervalMetres): ContourLine[]`: marching-squares algorithm over tile grid; groups adjacent edge crossings into polylines; closes loops. Tests: flat tile → no contours, slope tile → contours at expected elevations, closed contour for circular hill shape.
---
## 4. OTel instrumentation
- [ ] Span `heightmap.pyramid_build` with attribute `heightmap.zoom`; counter `heightmap.tile_encode_total`; histogram `heightmap.encode_duration_ms`.
---
## 5. Property-based tests (`tests/property.test.ts`)
- [ ] Delta encode/decode round-trip: for arbitrary `Int16Array` of length 256, `deltaDecode(deltaEncode(tile)).data` equals original.
- [ ] Tile coordinate arithmetic: `latLngToTileCoord(tileCoordToLatLng(coord), coord.z)` returns same coord for arbitrary valid coords.
- [ ] Contour bounds: all elevation values in `ContourLine[]` from `extractContours(tile, interval)` lie within `[tile.minElevation, tile.maxElevation]`.
---
## 6. Benchmarks (`src/__benchmarks__/heightmap-tiles.bench.ts`)
- [ ] `encodeTile` for 256×256 float32 tile.
- [ ] `decodeTile` for same.
- [ ] `extractContours` for 256×256 tile with 10 m interval.
---
## 7. Docs + verify
- [ ] One `.md` per implementation file (≥200 words, both examples, API reference). Root `README.md`.
- [ ] `bunx turbo lint typecheck test --filter=@suaveplan/heightmap-tiles` — green.
- [ ] `bunx turbo test:coverage --filter=@suaveplan/heightmap-tiles` — 100%.
- [ ] `bun scripts/publish.ts --package @suaveplan/heightmap-tiles`.
- [ ] Archive: `openspec/archive/2026-04-24-enterprise-heightmap-tiles/`.