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

7.1 KiB

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

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

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

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

interface HeightmapTileStore {
  get(coord: TileCoord): Promise<HeightmapTile | undefined>
  put(tile: HeightmapTile): Promise<void>
  delete(coord: TileCoord): Promise<void>
  list(zoom: number, box?: BoundingBox): AsyncGenerator<TileCoord>
}

function createMemoryTileStore(): HeightmapTileStore

class TilePyramidBuilder {
  constructor(store: HeightmapTileStore, options?: PyramidBuilderOptions)
  addSourceTile(tile: HeightmapTile): Promise<void>
  buildLevel(zoom: number, options?: BuildLevelOptions): Promise<void>
  buildAll(minZoom: number, maxZoom: number): Promise<void>
}

function lookupElevation(
  store: HeightmapTileStore,
  lat: number,
  lng: number,
  zoom?: number
): Promise<ElevationResult>

function extractContours(
  tile: HeightmapTile,
  intervalMetres: number
): ContourLine[]

interface ContourLine {
  elevation: number
  points: LatLng[]
  closed: boolean
}

Error codes

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

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.