# OpenSpec Change: enterprise-heightmap-tiles - **Change ID**: enterprise-heightmap-tiles - **Package**: `@suaveplan/heightmap-tiles` - **Category**: universal - **Target path**: `universal/geo/heightmap-tiles` - **Status**: IN PROGRESS - **Date**: 2026-04-24 - **Reference spec**: `/mnt/s/web/suaveplan/enterprise/heightmap-tiles.md` --- ## Summary Deliver `@suaveplan/heightmap-tiles` on the genesis branch from scratch at enterprise quality. The package provides a delta-encoded heightmap tile pyramid with adaptive bit depth: tile encoding/decoding (raw float32, delta-encoded uint16, uint8 at configurable bit depths), tile coordinate arithmetic (XYZ → bounding box, lat/lng → tile XYZ, tile overlap detection), a tile pyramid builder that down-samples tiles level by level via bilinear interpolation, a `HeightmapTileStore` interface with in-memory and file-system adapters, elevation lookup at arbitrary lat/lng by trilinear interpolation across tiles, contour-line extraction at configurable intervals, and a streaming tile import from GeoTIFF-style input buffers. Genesis adds structured errors, Zod schemas, OTel instrumentation, and property-based tests. --- ## Current-state audit (genesis) The package does not exist on genesis yet — this is a fresh build. --- ## Available workspace deps on genesis | Package | Role | |---|---| | `@suaveplan/error` (`workspace:^`) | `HeightmapError`; `HEIGHTMAP.*` error codes | | `@suaveplan/types` (`workspace:^`) | `LoggerLike`, `Clock` | | `@suaveplan/geo` (`workspace:^`) | `LatLng`, `BoundingBox`, coordinate utilities | | `@suaveplan/serialize` (`workspace:^`) | Binary tile serialization (MessagePack profile) | | `zod` (`catalog:forms`) | Schema validation | | `@opentelemetry/api` (`catalog:observability`) | Spans + counters | Dev deps: `vitest`, `@vitest/coverage-istanbul`, `fast-check` (all `catalog:testing`). --- ## Public API surface ### Core types ```ts type BitDepth = 8 | 16 | 32 interface TileCoord { x: number y: number z: number // zoom level } interface HeightmapTile { coord: TileCoord width: number // pixels; must be a power of 2 height: number bitDepth: BitDepth minElevation: number // metres maxElevation: number data: Uint8Array | Uint16Array | Float32Array encoding: 'raw' | 'delta' } interface ElevationResult { lat: number lng: number elevation: number // metres; NaN if no tile data confidence: 'exact' | 'interpolated' | 'extrapolated' } ``` ### Codec ```ts function encodeTile(tile: HeightmapTile, options?: EncodeOptions): Uint8Array function decodeTile(data: Uint8Array): HeightmapTile function deltaDecode(tile: HeightmapTile): HeightmapTile // converts delta → raw in place function deltaEncode(tile: HeightmapTile): HeightmapTile // converts raw → delta ``` ### Tile coordinate utilities ```ts function latLngToTileCoord(lat: number, lng: number, zoom: number): TileCoord function tileCoordToBoundingBox(coord: TileCoord): BoundingBox function tileCoordToLatLng(coord: TileCoord): LatLng // NW corner function tilesInBoundingBox(box: BoundingBox, zoom: number): TileCoord[] function tileParent(coord: TileCoord): TileCoord function tileChildren(coord: TileCoord): TileCoord[] ``` ### `HeightmapTileStore` and pyramid ```ts interface HeightmapTileStore { get(coord: TileCoord): Promise put(tile: HeightmapTile): Promise delete(coord: TileCoord): Promise list(zoom: number, box?: BoundingBox): AsyncGenerator } function createMemoryTileStore(): HeightmapTileStore class TilePyramidBuilder { constructor(store: HeightmapTileStore, options?: PyramidBuilderOptions) addSourceTile(tile: HeightmapTile): Promise buildLevel(zoom: number, options?: BuildLevelOptions): Promise buildAll(minZoom: number, maxZoom: number): Promise } function lookupElevation( store: HeightmapTileStore, lat: number, lng: number, zoom?: number ): Promise function extractContours( tile: HeightmapTile, intervalMetres: number ): ContourLine[] interface ContourLine { elevation: number points: LatLng[] closed: boolean } ``` ### Error codes ```ts type HeightmapErrorCode = | 'HEIGHTMAP_TILE_NOT_FOUND' | 'HEIGHTMAP_DECODE_FAILED' | 'HEIGHTMAP_ENCODE_FAILED' | 'HEIGHTMAP_INVALID_COORD' | 'HEIGHTMAP_PYRAMID_FAILED' | 'HEIGHTMAP_CONTOUR_FAILED' ``` --- ## Genesis additions 1. **`HeightmapError`** extends `SuaveplanError` with six stable codes. 2. **Zod schemas** for `TileCoord`, `HeightmapTile`, `ElevationResult`, `ContourLine`, `EncodeOptions`, `PyramidBuilderOptions`. 3. **Adaptive bit depth** — encoder selects the minimum bit depth that preserves the tile's elevation range to within 0.1 m precision; this is overridable via `EncodeOptions.bitDepth`. 4. **Delta encoding** — adjacent pixel differences are stored as integer deltas, compressing well via the built-in binary serializer; decode restores original values exactly (lossless for int16/int8, lossy for float32 at bit depth < 32). 5. **Bilinear interpolation** — `lookupElevation` fetches the surrounding tile grid and performs bilinear interpolation over the four nearest pixels. 6. **OTel instrumentation** — span `heightmap.pyramid_build` with attribute `heightmap.zoom`; counter `heightmap.tile_encode_total`; histogram `heightmap.encode_duration_ms`. 7. **Property-based tests** — delta encode/decode round-trip for arbitrary float32 tiles; tile coordinate arithmetic (lat/lng → coord → bbox → contains lat/lng); contour elevation values are within `[minElevation, maxElevation]`. --- ## File layout ```text universal/geo/heightmap-tiles/ package.json tsconfig.json vitest.config.ts src/ index.ts error-codes.ts constants/ index.ts types/ common.ts common.md codec/ tile-codec/ tile-codec.ts tile-codec.md tile-codec.test.ts index.ts delta-codec/ delta-codec.ts delta-codec.md delta-codec.test.ts index.ts coords/ tile-coords/ tile-coords.ts tile-coords.md tile-coords.test.ts index.ts store/ tile-store/ tile-store.ts tile-store.md tile-store.types.ts tile-store.test.ts index.ts memory-store/ memory-store.ts memory-store.md memory-store.test.ts index.ts pyramid/ pyramid-builder/ pyramid-builder.ts pyramid-builder.md pyramid-builder.test.ts index.ts elevation/ elevation-lookup/ elevation-lookup.ts elevation-lookup.md elevation-lookup.test.ts index.ts contour-extractor/ contour-extractor.ts contour-extractor.md contour-extractor.test.ts index.ts __benchmarks__/ heightmap-tiles.bench.ts tests/ integration.test.ts property.test.ts ``` --- ## Impact **Downstream consumers**: `@suaveplan/osm-buildings` (terrain elevation for 3D building placement), any 3D mapping/terrain rendering service. **Workspace dep prerequisites**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/geo`, `@suaveplan/serialize`.