Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

San Francisco in Miniature

Live: hausfath.github.io/sf-train-set

An interactive 3D model-railroad layout of San Francisco, built in the browser with three.js. The layout sits on a wooden table and follows the city's real geography: SRTM terrain, the OpenStreetMap shoreline, arterial streets, parks, 140,000 building footprints, and the real alignments of Caltrain, three Muni Metro lines, the F Market streetcar, the three cable car lines and three ferry routes. Trains shuttle end to end along those routes (diving into the Sunset, Twin Peaks and Market Street tunnels), ferries cross the bay, Karl the Fog rolls in from the Pacific, and the day/night cycle lights the windows downtown and the Bay Lights on the bridge.

Everything is a single self-contained index.html (about 2.3 MB, data inlined) that loads three.js from a CDN. Open it locally with any static server:

python3 -m http.server 8765   # then visit http://localhost:8765/index.html

Controls

Action How
Orbit / zoom / pan left-drag / scroll / right-drag
Info card click a landmark, a bridge or a train
Ride along click a train in the "Rolling stock" list, or keys 1–9 (0 = free camera)
Time of day slider, or N to jump between day and night; "Auto day/night" cycles a day in four minutes
Fog slider, or F
Labels / tour / reset L / T / R, or the buttons
Pause trains space

Pipeline

data/fetch_data.py     Overpass (OpenStreetMap) pulls for the bbox 37.70–37.84 N, 122.53–122.33 W:
                       coastline, water, parks/forest/beach, roads (motorway→tertiary), piers,
                       buildings with heights, towers, bridges, and the transit route relations
data/fetch_elev2.py    101 × 71 elevation grid (about 180 m spacing) from open-elevation.com (SRTM)
data/process_data.py   shapely: assemble land polygons from coastline ways (left-hand rule with a
                       majority vote), simplify everything, chain route relation members into
                       ordered polylines with tunnel flags, pack building footprints as oriented
                       rectangles into an 8-byte/building binary blob  →  data/sf_data.json (2.1 MB)
src/*.js, src/head.html   the app, split into setup/terrain, city, rail, landmarks, main
build.py               inlines sf_data.json and the JS modules into index.html

Re-running fetch_data.py re-downloads about 175 MB of raw OSM JSON (the buildings file alone is 160 MB); the processed sf_data.json and elev.json are kept in the repo so the site can be rebuilt without re-downloading. The raw pulls are deleted after processing.

Scale and conventions

  • 1 scene unit = 100 m horizontally. Terrain relief is exaggerated 2×, buildings and landmark models 1.5× (so skyscrapers do not turn into needles). Vehicles are drawn at about 2.4× their real footprint so they read as toy trains.
  • The DEM is SRTM at ~90 m, sampled on a 180 m grid and smoothed; Twin Peaks comes out at ~250 m rather than 282 m. Land is forced to at least 3 m above the water plane so the shoreline reads as a seawall.
  • Rail routes are the OpenStreetMap public-transport route relations (one direction each): Caltrain Local, N Judah, L Taraval, T Third, F Market & Wharves, Powell–Hyde, Powell–Mason, California Street, plus the Sausalito, Oakland and Treasure Island ferries. Tunnel members (tunnel=yes) dip below the terrain between portals. Trains reverse at the ends of each route (and at the table edge for Caltrain and the ferries).
  • Tower positions for the Golden Gate Bridge and the Bay Bridge west span are the man_made=tower features in OSM; deck and tower heights are hand-set (67 m / 227 m and 58 m / 160 m). Landmark models (Transamerica Pyramid, Coit Tower, Palace of Fine Arts, Sutro Tower, City Hall, Painted Ladies, …) are hand-built from primitives at their real coordinates and aligned to the local street grid using the orientation of nearby OSM footprints. The generic 45 m+ downtown towers are the real OSM footprints extruded to their tagged heights.
  • Streets are painted onto a 4096 px ground texture, not modelled in 3D; the residential grid is implied by the buildings themselves.

Rendering the flythrough video

index.html?record puts the page in director mode: the camera, clock and fog follow a scripted shot list (src/p6_director.js) in simulated time and SF.frame(t) renders one frame. video/render.mjs drives that with puppeteer-core, screenshots every frame and encodes an MP4:

cd video && npm install          # puppeteer-core only; uses a local Chrome (set CHROME=/path if needed)
cd .. && python3 -m http.server 8765 &
node video/render.mjs 30 1920 1080   # → video/sf-train-set.mp4 (about 48 s)

Data licences

Map data © OpenStreetMap contributors, ODbL. Elevation: NASA SRTM via open-elevation.com. Code: MIT. Landmark blurbs were written from general knowledge and should be spot-checked before quoting.

About

San Francisco as an interactive 3D model train set, built on real terrain and OpenStreetMap geometry

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages