Project Info
Inspiration
Every one of us has moved to a city where we knew nobody. The first few weeks are the same disorienting blur: Which neighborhood should I live in? Is that commute actually bearable? Where do people like me hang out? Is this area my speed or not? Tourist apps answer "what should I see this weekend" but nobody builds for the person who has to figure out a whole life in a place they've never lived. Google Maps shows you streets. Zillow shows you listings. Niche shows you a wall of statistics. None of them let you feel a city before you arrive. We wanted the thing we all wished we'd had on day one: a local friend who flies you through your new city in 3D, talks you through each neighborhood, and helps you find where you actually belong. That's Homing.
What it does
Homing turns "I'm moving to a new city" from a spreadsheet of unknowns into a guided, explorable experience. Fly through your new city in 3D. Real photorealistic 3D tiles, not a flat map. Orbit, pan, and zoom over actual buildings and terrain. Take a narrated tour. A camera-on-rails ride glides you stop-to-stop along real transit lines while a voice (powered by Deepgram) narrates each place like a local showing you around. Explore neighborhoods with real context. Click a district to see its character, population, density, median income, dominant industries, and climate — the stuff that actually decides whether you'd live there. Check your commute. Drop in two addresses and compare drive / transit / bike / walk times and distances, with the route drawn on the 3D map. Everything the UI renders comes from a single City data object, so a new city is one data file away.
How we built it
Frontend: React 19 + TypeScript, Zustand for state, Tailwind for styling, Vite for the build. 3D engine: CesiumJS rendering Google Photorealistic 3D Tiles through the Map Tiles API. Voice: Deepgram text-to-speech streams narration that stays in sync with the camera as it moves between tour stops. Routing: Google Routes API for multimodal commute comparison, with results geocoded and drawn as polylines on the globe. Architecture: a fully data-driven city model — places, tours, districts, and quests are pure data, so the picker, map, explore mode, and tour mode, all light up automatically for any new city. The guided tour is the technical heart. Instead of teleporting the camera between stops, we build a smoothed spline through the route's control points and interpolate the camera along it. For control points $Not disclosed$ and a local parameter $t \in [0,1]$, we evaluate a Catmull–Rom segment: Not disclosed $$ which gives the camera a continuous, train-like glide instead of robotic jumps. Commute distances use the haversine formula over the WGS-84 sphere: Not disclosed
Challenges we ran into
Syncing voice to motion. Getting Deepgram narration to start, pace, and finish in lockstep with a moving camera — without audio cutting off mid-flight or lagging behind the visuals — took real tuning of the playback and tour-advance lifecycle. Taming the camera. Photorealistic 3D tiles look incredible but make camera control unforgiving: pitch, heading, and height all interact, and a naive path through waypoints felt nauseating. The spline interpolation above was our fix. 3D tile performance. Streaming gigabytes of 3D tiles while keeping the UI responsive meant being careful about when we fly, preload, and render overlays. Graceful degradation. The app depends on third-party keys (Cesium Ion, Google Maps). Rather than show a broken globe, we built a friendly "add your keys" state so the experience never hard-crashes. Designing for relocators, not tourists. Our hardest product challenge was resisting the tourist framing. Every feature had to answer "does this help someone decide where to live?" which is why neighborhoods carry demographics and commute math, not just pretty photos.
Accomplishments we're proud of
A genuinely cinematic 3D city tour with synchronized AI voice narration that feels like a friend, not a robot. A data-driven architecture where adding an entire new city is one file no UI changes. Real, decision-grade neighborhood context (income, density, industries, climate) fused with live multimodal commute routing on the same 3D map. We shipped all of it as a small team in a hackathon timebox.
What we learned
CesiumJS + Google 3D Tiles from the ground up, camera math, splines, and the art of making 3D navigation feel good rather than dizzying. Streaming TTS is a UX problem, not just an API call - timing and lifecycle matter more than the audio itself. Constraints make products. Narrowing from "explore any city" to "help someone relocate" sharpened every design decision. Data modeling is leverage - investing early in a clean City schema paid for itself the moment we wanted to scale beyond one city.
What's next
More cities, fast - our data-driven model means national coverage is a content problem, not an engineering one. A "neighborhood fit" engine - tell us your budget, commute, and lifestyle, and we recommend where to live, then learn from whether the fit was right. That outcome data is something no map or listings site has, and it's the moat we're building toward. End-to-end relocation workflow - from "where should I live" through housing, commute, and a settle-in checklist, so Homing becomes the system of record for an entire move. Voice-first concierge - ask "where should someone like me live in this city?" out loud and take the tour that answers it. Embedded distribution - partnering with employers, universities, and relocation services to reach people at the exact moment they're moving.
City Explorer
A simple, 3D, gamified way for someone new to a city to get the lay of the land. Pick a city, then either ride a guided tour (camera on rails) or explore in 3D (free-roam map, click places to learn about them). v1 supports the Bay Area.
Built on CesiumJS with Google Photorealistic 3D Tiles, the feeling we're after is a local friend showing a newcomer around.
Run it
npm install
cp .env.example .env # then fill in your two keys (see below)
npm run dev # http://localhost:5173
API keys (both have free tiers)
.env needs:
VITE_CESIUM_ION_TOKEN— from https://ion.cesium.com/tokensVITE_GOOGLE_MAPS_KEY— a Google Maps Platform key with the Map Tiles API enabled
Without keys the app shows a friendly "add your keys" panel instead of a broken map.
How it works
- Pick a city → pick a mode → the 3D map.
- Explore: orbit/pan/zoom; click a pin to fly there and read a blurb.
- Tour: camera glides stop-to-stop with narration; advance via buttons, scroll, or arrow keys.
- Passport (top-right): collects a stamp per discovered place, tracks "X of N discovered", and awards badges for quests. Persists in localStorage.
Adding another city
Everything the UI renders comes from a City data object — no city is hardcoded.
To add one:
- Create
src/data/cities/<city>.tsexporting aCity(places, tours, quests, anintrocamera view). Usesrc/data/cities/bay-area.tsas the template. - Add it to the registry in
src/data/cities/index.ts.
That's it — the picker, map, explore, tour, and passport all pick it up.
Project structure
src/
data/ types.ts + cities/ (all content lives here)
state/ zustand stores: app screen, passport, quests
cesium/ viewer hook, camera helpers, pins
screens/ CityPicker, ModePicker, MapView, ExploreMode, TourMode
components/ PlacePanel, Passport, BadgeToast, Fog, MissingKeys
Notes
- Place coordinates are approximate and camera framings use sensible defaults —
tune per place in
bay-area.tsas desired. - Restrict your Google Maps key (HTTP referrers + Map Tiles API only) before deploying anywhere public.
Analysis
View
Metric
- 8
- 4
- 2
- 1
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- AnthropicIn code
- CSSIn code
- ExpressIn code
- HTMLIn code
- JavaScriptIn code
- ReactIn code
- Tailwind CSSIn code
- TypeScriptIn code
- Node.jsClaimed
8 of 9 appear in the indexed code. 1 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
No AI coding agent signals were found in this repository.
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
287 KB
Source files
61
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
sprothia/3dmap-calhack
72 files · 501 KB · @ 151f745
Structure
Interface
24 files · 33%Screens, components and styles rendered to the user.
API & routing
5 files · 7%Request entry points: routes, handlers and controllers.
Application logic
29 files · 40%Domain rules, services and shared utilities.
+2 more
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- TypeScript89%
- CSS5%
- JavaScript4%
- Markdown1%
- HTML0%
- YAML0%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
package.json
npm · 28- @anthropic-ai/sdk
- @browserbasehq/sdk
- @types/three
- cesium
- cors
- express
- playwright-core
- react
- react-dom
- three
- tslib
- vite-plugin-cesium
- zustand
- +15 more
Declared in the repository’s manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
This project’s features have not been analysed yet.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.