Skip to content

Chatt twin coverage: match the official Chattanooga city-limits boundary (nothing more/less) — phased 8k→100k #326

Description

@TortoiseWolfe

North star

Twin coverage should equal the official incorporated City of Chattanooga boundary — exactly, nothing more or less: everything inside the municipal limits, and nothing outside (NOT Hamilton County, NOT the separate municipalities of East Ridge / Red Bank / Lookout Mountain / Signal Mountain, NOT unincorporated pockets). A visible boundary line in the twin, and copy that is honest about how much of the city is actually rendered at any given phase.

Why this is a new dimension (and why a bbox can't do it)

Coverage today is defined purely by axis-aligned lat/lon rectanglessites/chatt.json box + atlasBox, unioned in scripts/bake/site-config.ts (atlasBoxFor); every filter is a bbox test (build-scene.ts inBox, Liang–Barsky rectangle clip; the Overpass queries in scripts/bake/fetch-osm.ts are bbox-only). There is no municipal-boundary polygon anywhere in the repo.

Chattanooga's incorporated boundary is famously irregular — decades of annexation, with hard "holes" for the separate cities and unincorporated pockets. A rectangle both includes non-city edges and excludes most of the city. So this needs a real boundary polygon + a point-in-polygon clip, not a bigger rectangle.

This is orthogonal to the existing accuracy program (#229 / #225 / #233), which only tracks layer registration within the box (OSM↔drape↔terrain alignment, building heights). Coverage-vs-city-limits is a genuinely new accuracy axis.

Current state

  • /chatt atlas is deliberately downtown-scoped: model-city-prd.md "digital twin of downtown Chattanooga" (MC-1: Riverfront→Southside, North Shore), ~8,031 buildings.
  • Shipped atlas extent ≈ lat 35.0078–35.076 N, lon −85.345–−85.283 W (~7 km × 7.6 km around downtown).
  • The full incorporated city is ~137 sq mi / 100k+ buildings — a ~12× area jump the single-baked-JSON runtime + per-model perf budget are not architected for. Hence phased.

Phase 1 — make it honest + reach the client (buildable now)

  1. Source the boundary polygon (see Data source) → store as public/twins/chatt/city-limits.geojson; reference it from sites/chatt.json via a new schema field (e.g. cityLimits GeoJSON ring), distinct from the rectangular box/atlasBox (extend SiteConfigSchema in scripts/bake/site-config.ts).
  2. Point-in-polygon clip at bake time — drop buildings whose centroid falls outside the city polygon (augment/replace the inBox rectangle test in build-scene.ts). Reuse the existing point-in-polygon helper (src/lib/manifest.ts, currently anchor-in-footprint) rather than adding turf. Result: nothing outside the city limits renders, even within the covered rectangle → satisfies "nothing more."
  3. Boundary overlay in the twin — render the city-limits polygon as a Cesium boundary line (thin new layer in AtlasViewer.client.tsx) so the viewer SEES "this is Chattanooga." Verify via the ?topdown orthographic mode + .chatt-verify/capture.mjs; optionally emit a coverage metric into manifest.json beside the Digital twin: repeatable footprint-verification report — every building, every bake, hard thresholds #233 registration report.
  4. Reach the 2630 E Main St client — grow the atlas extent E/SE along the E Main corridor to absorb the separate sites/east-main-street-chattanooga.json island (box lon −85.276→−85.258), bridging the gap from the downtown atlasBox (ends at lon −85.283). The client at 2630 E Main St (near Old Ringgold Rd / Ryan St / Missionary Ridge / I-24) is confirmed inside the City of Chattanooga, so the twin should cover it. First real step up the 8k→100k gradient; proves the coverage-growth mechanism on a client-driven anchor. (Rebake required — heavy: Overpass + drape + 3DEP + lidar.)
  5. Honest labeling — the atlas HUD/copy states it renders a subset (downtown + the E Main corridor) of the full city, with the boundary shown for context.

Phase 2 — full-city (north star; tracked, not scoped)

Expand to the entire city polygon at building detail (~100k+ buildings). Requires re-architecting beyond the single baked JSON: LOD / tiling (3D Tiles or chunked baked layers), streaming, a perf budget that scales, and a bake that fans out over the whole polygon. Open questions to resolve when scoped:

  • Tiling scheme + memory budget + target frame rate at full extent.
  • Bake time/cost over ~137 sq mi; Overpass-per-tile vs. a bulk OSM extract (Geofabrik).
  • Whether Microsoft/Google ML building footprints supplement OSM where OSM is sparse (note: "~85% of downtown buildings are untyped in OSM" today — a separate data-quality gap, cross-referenced not conflated).

Data source (recommend; final pick at implementation)

  • US Census TIGER/Line "Places" — Chattanooga FIPS 4714000 (top rec): the official incorporated-place polygon, free + programmatic + token-free (matches the twin's no-ion ethos), refreshed annually via BAS. Reproducible.
  • Hamilton County RPA / GIS ArcGIS or TN state ArcGIS (tnmap.tn.gov, already the imagery source): most locally authoritative for recent annexations — use as a cross-check.
  • OSM admin_level=8 relation (convenient via the existing Overpass path) — but can lag annexations; not authoritative for "officially."

New fetcher scripts/bake/fetch-city-limits.ts, mirroring fetch-osm.ts / fetch-drape.ts.

Cross-references

Acceptance (Phase 1)

  • A city-limits.geojson (Census/Hamilton Co.) loads; the twin renders the boundary line.
  • The bake clips to the polygon: a building known to be just OUTSIDE the city limits (e.g. in Red Bank / East Ridge) does NOT render; in-city buildings do.
  • The 2630 E Main St client renders as part of the main /chatt atlas (not a separate site), reachable by panning from downtown.
  • Copy honestly states the rendered subset; ?topdown screenshot shows coverage against the boundary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestevalSurfaced as a candidate for an eval/pre-work sprint.eval-3Enterprise-realism rank 3 — hard backend task on a template-framed repo

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions