Behind the 3D: How We Mapped Every Honolulu Building Footprint with Real Heights
The Hawaii 3D map at ai.ikenagroup.com/3d renders every parcel statewide and every Honolulu building footprint with accurate extruded heights. It runs in a browser tab, no server-side tile rendering, no API keys. Here's how it's built — and why all 56 million lines of source data live in TypeScript.
The premise
Hawaii's parcel and building data is fully public. The State Office of Planning publishes statewide parcels via ArcGIS REST. Honolulu DPP publishes building footprints. The City & County publishes address points. None of these come pre-joined or pre-3D-extruded, and the official viewers (HoLIS, Hawaii GIS Program) are slow server-side renderers locked to per-county scopes.
The premise behind hawaii-as-code was: scrape the
public data once, encode it as static TypeScript files, ship them
behind a CDN, render the entire dataset in the browser. No
database, no API key, no rate-limited tile server. The browser
holds the whole island in memory.
Why TypeScript files, not Postgres
Counterintuitive choice. Most spatial projects start with PostGIS. A few reasons we went the other way:
- Static deploys to anywhere. The whole dataset is files. Cloudflare Pages, Vercel, S3 + CloudFront, GitHub Pages — anywhere static hosting works, the map works. No database to provision.
-
Type-safe queries at compile time. The
generator emits per-parcel TypeScript:
{ tmk_txt: "12100100", gisacres: 0.34, zone: "R-5", island: "OAH", ... }. Your IDE autocompletes parcel fields. Bad TMK references fail at build time, not at the user's request. - Versioning is git. Every parcel update is a diff in source control. Five years from now anyone can git-blame a TMK and see when its zoning code last changed.
- Bandwidth is low. The browser only loads the bbox-relevant batches. A typical zoom-in pulls ~150 KB of gzipped GeoJSON, not the whole island.
The pipeline (rough sketch)
┌──────────────────────────────────────────────┐
│ 1. Scrape statewide parcels from ArcGIS REST │
│ geodata.hawaii.gov/.../ParcelsZoning │
│ 1000-parcel batches, polite delay 250ms │
│ Checkpoint + resume on failure │
└──────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ 2. Per-batch JSON → per-parcel .ts files │
│ packages/parcels/src/{island}/{plat}/ │
│ {tmk}.ts │
│ Each file ~47 lines, fully typed │
└──────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ 3. Honolulu DPP building footprints │
│ GeoJSON download, parse with proj4 to │
│ EPSG:4326, extract per-building height │
│ from elevationmax — elevationbase │
└──────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ 4. Address-point index │
│ Honolulu open data CSV → searchable │
│ in-memory index, mapped to TMK │
└──────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ 5. MapLibre + WebGL rendering │
│ Bbox-aware lazy load │
│ Fill polygon for parcels │
│ Extrude polygon for buildings │
│ Time-of-day shading via SunCalc │
└──────────────────────────────────────────────┘
Building heights — the hard part
Honolulu DPP's building-footprint dataset includes per-feature
elevationbase and elevationmax values.
Subtract one from the other and you get usable building height in
meters above the foundation. Pass that to MapLibre's
fill-extrusion-height property, and every building
in downtown Honolulu, Waikiki, and the residential ridges renders
at correct height.
Caveats:
- Roof type matters. The dataset gives you the max elevation, which for a pitched-roof house is the ridge, not the eave. Extruding to ridge height makes a single-family home look slightly taller than it "feels" walking up to it.
- Coverage is Honolulu-only. Maui, Hawaii Island, and Kauai don't publish equivalent height data. Their buildings show as flat parcel polygons until those counties publish.
- Updates lag construction. The DPP footprints were last refreshed in early 2025. New construction since then isn't in the dataset.
Performance — what makes the browser handle 384k parcels
Three tricks:
- Bbox lazy load. The map only requests the batches that intersect the current viewport. Zoomed out to the whole state, the browser loads <5,000 parcels. Zoomed into Kahala, ~1,200. We never push more than a few hundred KB of JSON in any single tick.
-
Server-side cache. The Node server reads each
batch JSON from disk once, holds in-memory. Subsequent fetches
serve from RAM.
~/server/hawaii-as-code/scripts/serve-api.tshandles all of this in a single ~1700-line file. - MapLibre handles the rest. WebGL polygon fill + extrusion is one of the cheapest things a modern GPU can render. The bottleneck is JSON parsing, not GPU upload.
What it took
The first scrape ran 11 hours (rate-limited politely to not abuse the State GIS server). Building-footprint join took another 3 hours. Address-point indexing was an afternoon. The MapLibre rendering layer was 2 days of styling iteration. The TypeScript generator + per-parcel emission was the longest single chunk — roughly a week to get the schema, naming, file layout, and rollup indexes feeling right.
Total wall-clock from "this would be cool" to public-facing live
map: ~10 days. Codebase open-sourced on GitHub at
portofcams/hawaii-as-code.
What it's for
The 3D map is the visual surface for everything else IkenaAI does. Click a building, see its TMK + parcel info. Search an address, fly to the parcel. Run a Property Brief from the popup. The map is also the marketing front-door — it's the kind of thing you show people once and they never forget the URL.
Open the 3D map
Best on desktop with a real GPU. Pan, zoom, click any building, time-of-day shading, voice control.
Open the map →What's next
- Maui + Hawaii County + Kauai building extrusions once those counties publish equivalent height data.
- Time-machine slider to see Honolulu's skyline grow from 1970 forward (from historical aerial photo height backfill).
- Permit overlay showing active permits as colored markers floating over their parcels.
- SKU catalog overlay — for contractors, click a parcel, see nearest City Mill / HPM stock + pricing.
We'll write up each as it ships. Bookmark the Field Notes if interested.