Render print-quality Project PLATEAU city maps in your browser.
The hosted live demo for the prettyplateau library.
Pick a city, preset, theme, and format, and render a print-quality city map
(PNG / SVG / PDF / mp4) in the browser. This is the in-browser live demo for the
prettyplateau rendering library.
Part of Yodo Labs' open-source PLATEAU toolkit:
prettyplateau (rendering, what
this demo runs) · plateau-bridge
(the building-data pipeline it reads) ·
plateau-risk-lens (a separate
sibling — a 2D disaster-risk map explainer).
Nine static presets (usage, height, flood depth, risk, building age, zoning,
density…) × six themes × PNG / SVG / PDF, plus an mp4 survivor-timeline
animation — all driven live by prettyplateau.
![]()
Survivor Timeline — Fukuoka's buildings revealed in order of year built (prerendered mp4).
web (static, Vite+React) ──POST /api/render──► render-service (FastAPI, Python)
Cloud Run nginx Cloud Run, min-instances=0
prettyplateau[animation]
│
data: public plateau-bridge (29 cities)
cache: GCS (optional) / local dir
- render-service is a thin wrapper around
prettyplateau.render. All input is white-listed (allowlist.py); a cache-first path means repeat combinations cost zero compute. - Live vs prerendered: cities under ~150k buildings render on demand; larger cities and all mp4 animations are shown as examples in the gallery (server-side matplotlib is memory- and CPU-bound, so big cities would take minutes).
Requires the sibling ../plateau-core checkout (the plateau-bridge data) — or
the service will fetch cities from the public index on first use.
# 1. render-service
python3 -m venv .venv
.venv/bin/pip install -e "../prettyplateau[animation]" fastapi "uvicorn[standard]"
cd render-service
DATA_ROOT=../../plateau-core ../.venv/bin/python -m uvicorn app:app --port 8100
# 2. frontend (separate shell)
cd web
npm install
npm run dev # http://localhost:5174 — proxies /api to :8100End-to-end smoke test (boots the service, exercises every endpoint + guardrail):
bash scripts/smoke.sh| Method | Path | Purpose |
|---|---|---|
| GET | /api/healthz |
liveness (under /api — Cloud Run's GFE intercepts bare /healthz) |
| GET | /api/options |
white-listed cities / presets / themes / formats |
| POST | /api/render |
render one artifact (cache-first), returns the bytes |
POST /api/render body: { "city", "preset", "theme", "format", "width" }.
Two services in your GCP project (configured via repo variables/secrets — no project identifiers are committed):
render-service— 8 GiB / 2–4 vCPU,--concurrency=1,--min-instances=0,--max-instances=3,--timeout=900. SetCORS_ORIGINSto the web origin and (optionally)GCS_CACHE_BUCKETfor a persistent render cache.web— static build behind nginx;VITE_API_BASEpoints at the render-service origin.
CI auth uses Workload Identity Federation (secrets WIF_PROVIDER, DEPLOY_SA);
config lives in repo variables (GCP_PROJECT, GCP_PROJECT_NUMBER,
GCP_REGION, GCS_CACHE_BUCKET). Deploy is gated by the
CLOUDRUN_DEPLOY_ENABLED repo variable so forks and fresh checkouts never
auto-deploy. See .github/workflows/deploy.yml.
Optional: scripts/bake-data.sh bakes curated cities' parquet into the image
for instant first render.
See CONTRIBUTING.md for local setup and the invariants
PRs must respect (chief among them: attribution can't be disabled).
- Code: MIT (see
LICENSE) - Generated outputs carry © Project PLATEAU / MLIT (CC BY 4.0), embedded in the artifact and its metadata — it cannot be disabled.
- Third-party notices:
NOTICE.md