# OpenSpec Change: enterprise-osm-buildings - **Change ID**: enterprise-osm-buildings - **Package**: `@suaveplan/osm-buildings` - **Category**: universal - **Target path**: `universal/geo/osm-buildings` - **Status**: IN PROGRESS - **Date**: 2026-04-24 - **Reference spec**: `/mnt/s/web/suaveplan/enterprise/osm-buildings.md` --- ## Summary Deliver `@suaveplan/osm-buildings` on the genesis branch from scratch at enterprise quality. The package provides OpenStreetMap building and road geometry extraction and mesh generation: OSM XML/PBF-lite parsing, building footprint extraction from `building=*` relations and ways, road network extraction from `highway=*` ways, polygon simplification (Ramer-Douglas-Peucker), 2.5D extruded building mesh generation (flat roof, pitched roof from `roof:shape=*`), LOD (level of detail) tile pyramid for buildings, elevation offset from `@suaveplan/heightmap-tiles`, GeoJSON and flat-buffer mesh output, and a streaming feature extractor. 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:^`) | `OsmBuildingsError`; `OSM.*` error codes | | `@suaveplan/types` (`workspace:^`) | `LoggerLike` | | `@suaveplan/geo` (`workspace:^`) | `LatLng`, `BoundingBox`, polygon area, coordinate utilities | | `@suaveplan/heightmap-tiles` (`workspace:^`) | Elevation offset for 3D building placement | | `@suaveplan/serialize` (`workspace:^`) | Binary flat-buffer output serialization | | `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 interface OsmBuilding { id: string // OSM way/relation ID footprint: LatLng[] // exterior ring, counter-clockwise holes: LatLng[][] // interior rings height: number // metres; 0 if unknown minHeight: number // metres above ground; for bridges/overhangs levels?: number roofShape?: RoofShape tags: Record // raw OSM tags } type RoofShape = 'flat' | 'pitched' | 'hipped' | 'dome' | 'pyramidal' | 'unknown' interface OsmRoad { id: string points: LatLng[] highway: string // OSM highway value e.g. 'primary', 'residential' name?: string lanes?: number oneWay: boolean tags: Record } interface BuildingMesh { buildingId: string vertices: Float32Array // xyz triplets indices: Uint32Array // triangle indices uvs?: Float32Array // optional UV coords } ``` ### Parsers ```ts function parseOsmXml(xml: string, options?: ParseOptions): OsmFeatureSet function parseOsmPbfLite(buffer: Uint8Array, options?: ParseOptions): OsmFeatureSet interface OsmFeatureSet { buildings: OsmBuilding[] roads: OsmRoad[] bbox: BoundingBox } interface ParseOptions { bbox?: BoundingBox // filter to bounding box includeBuildings?: boolean // default true includeRoads?: boolean // default true signal?: AbortSignal } ``` ### Mesh generation ```ts function buildingToMesh( building: OsmBuilding, options?: MeshOptions ): BuildingMesh function buildingsToMeshes( buildings: OsmBuilding[], options?: MeshOptions ): BuildingMesh[] interface MeshOptions { store?: HeightmapTileStore // for elevation offset; optional lodLevel?: number // 0 = highest detail; higher = simplified uvScale?: number } ``` ### Simplification ```ts function simplifyPolygon(ring: LatLng[], toleranceMetres: number): LatLng[] function simplifyRoad(points: LatLng[], toleranceMetres: number): LatLng[] ``` ### Streaming extractor ```ts function createOsmFeatureStream(options?: ParseOptions): OsmFeatureStream interface OsmFeatureStream { writable: WritableStream // OSM XML or PBF-lite bytes readable: ReadableStream } ``` ### Error codes ```ts type OsmBuildingsErrorCode = | 'OSM_PARSE_FAILED' | 'OSM_INVALID_GEOMETRY' | 'OSM_MESH_FAILED' | 'OSM_ELEVATION_FAILED' | 'OSM_SIMPLIFY_FAILED' | 'OSM_ABORTED' ``` --- ## Genesis additions 1. **`OsmBuildingsError`** extends `SuaveplanError` with six stable codes. 2. **Zod schemas** for `OsmBuilding`, `OsmRoad`, `OsmFeatureSet`, `ParseOptions`, `MeshOptions`, `BuildingMesh`. 3. **PBF-lite parser** — supports a simplified subset of OSM PBF (nodes, ways, string table) without requiring a full protobuf library; implemented natively using `DataView` binary parsing. 4. **LOD pyramid** — `lodLevel` in `MeshOptions` controls polygon simplification tolerance (level 0 = 0 m, level 1 = 1 m, level 2 = 5 m, level 3 = 20 m) for progressive rendering. 5. **Elevation offset** — when a `HeightmapTileStore` is provided, building vertices receive a per-vertex Z offset from `@suaveplan/heightmap-tiles`; gracefully degrades to z=0 without a store. 6. **OTel instrumentation** — counter `osm.buildings_parsed_total`; span `osm.parse` with attribute `osm.format`; histogram `osm.mesh_build_duration_ms`. 7. **Property-based tests** — simplification never produces self-intersections; mesh index buffer references only valid vertex indices; Ramer-Douglas-Peucker preserves first and last points. --- ## File layout ```text universal/geo/osm-buildings/ package.json tsconfig.json vitest.config.ts src/ index.ts error-codes.ts constants/ index.ts types/ common.ts common.md parsers/ osm-xml-parser/ osm-xml-parser.ts osm-xml-parser.md osm-xml-parser.test.ts index.ts osm-pbf-parser/ osm-pbf-parser.ts osm-pbf-parser.md osm-pbf-parser.test.ts index.ts feature-extractor/ feature-extractor.ts feature-extractor.md feature-extractor.test.ts index.ts mesh/ building-mesher/ building-mesher.ts building-mesher.md building-mesher.types.ts building-mesher.test.ts index.ts roof-builder/ roof-builder.ts roof-builder.md roof-builder.test.ts index.ts geometry/ simplifier/ simplifier.ts simplifier.md simplifier.test.ts index.ts streaming/ osm-feature-stream/ osm-feature-stream.ts osm-feature-stream.md osm-feature-stream.test.ts index.ts __benchmarks__/ osm-buildings.bench.ts tests/ integration.test.ts property.test.ts ``` --- ## Impact **Downstream consumers**: 3D map rendering services. **Workspace dep prerequisites**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/geo`, `@suaveplan/heightmap-tiles`, `@suaveplan/serialize`.