尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗An isometric pixel-art map of Bengaluru, made the way tiny.london was made. This repo has stage 1 so far: one camera that renders the whole city from Google's Photorealistic 3D Tiles in shots that line up to the pixel.
cp .env.example .env # set GOOGLE_TILES_API_KEY (Map Tiles API + billing)
# or CESIUM_ION_TOKEN (same Google tiles via Cesium ion, free account)
uv sync
uv run playwright install chromium
cd render && bun install && cd ..
# 9 shots around Vidhana Soudha and Cubbon Park
uv run python -m blr.plan --center 12.9796,77.5907 --size-px 4096 --out runs/pilot
uv run python -m blr.render runs/pilot --workers 2
uv run python -m blr.mosaic runs/pilot --scale 0.25 # runs/pilot/mosaic.png
To look around by hand, run cd render && bun run dev and open http://127.0.0.1:5173/?shot=-1,-2. The arrow keys move one shot, and shift+arrow moves ten.
For the whole city, pass a boundary GeoJSON (BBMP/GBA, e.g. from OpenCity or DataMeet) to blr.plan --boundary, with --margin-px to grow the edge band.
uv run python -m blr.pyramid runs/pilot --version v1 # tiles -> site/public/tiles/v1
uv run python -m blr.search_index runs/pilot # site/public/search.json
cd site && bun install && bun run dev # http://127.0.0.1:5180
bun run build && bun run preview # production build
blr.pyramid builds a Deep Zoom pyramid of 512 px WebP tiles from the shots (use --source and --lossless for pixel art later). It refuses to write into an existing version, so tiles can be cached forever. site/public/_headers sets immutable for Cloudflare.index.html (vite.config.js). The boot script works out the first view and requests exactly the tiles the viewer will draw before the app bundle loads. The viewer loads only that level first, and coarser levels after.#lat,lon,scale (scale is screen px per map px), so any address can be shared. Share copies it./ focuses the search box.uv run python -m blr.layers runs/pilot → site/public/layers.json): Namma Metro lines in their official colours, with tunnels dashed and elevated track lifted 12 m. GBA city corporations and wards, with shared borders merged so each draws once, and labels placed on the visible part of each area. Every vertex is projected at its own SRTM ground height.uv run python -m blr.clouds runs/pilot → site/public/clouds/): a harmonic field, solved from Laplace's equation, that is 0 over the city and 1 far outside it, so no cloud can appear over the city and the cloud edge never traces the boundary's zigzags. The shader in src/clouds.js adds drifting puffs and draws chunky pixels anchored to the map, with an outline and lit and shaded rims. It runs at 15 fps and only while clouds are on screen, and stays still if the user prefers reduced motion. For the full city, pass --region <GBA boundary.geojson>.src/projection.js is camera.py ported to JavaScript, and tests/test_site.py keeps the two identical.vercel.json deploys site/ only. Tile images are not in git (the version pointer, manifests and search.json are), so host site/public/tiles/<version>/tiles_files/ somewhere built for many static files, such as a Backblaze B2 bucket with CORS allowed for the site's domain (see docs/HANDOFF.md), and set TILE_BASE in the build environment to its URL (the folder holding <version>/tiles_files/). Without TILE_BASE, tiles load from the site's own /tiles. If the build also has B2_KEY_ID and B2_APPLICATION_KEY, the bucket is treated as private and site/api/tile-token.js supplies a download token for the tile URLs.
uv run python -m blr.frames runs/pilot # 1,024 px frames + OSM water masks
uv run python -m blr.teacher runs/pilot --dry-run # write prompts, show the cost cap
uv run python -m blr.teacher runs/pilot --limit 6 # draw six frames
uv run python -m blr.contact runs/pilot # runs/pilot/teacher/contact.png
blr.frames cuts each shot into four 1,024 px frames. It fetches OSM water (Overpass) and places each lake at its own SRTM height plus srtm_to_ellipsoid_m (−65 m, measured on the pilot from pools and lakes). Each frame gets a "WATER IN THIS VIEW" sentence and three masks.blr.teacher sends each frame with prompts/teacher.txt, which says how to draw, never what to draw. Each attempt is checked against ground truth:
teacher/attempts.jsonl, and accepted drawings go to teacher/targets/. Rerunning resumes where it stopped.config/teacher.json (gemini or openrouter) or with --provider. Gemini 3 Pro Image costs about $0.135 per call.config/teacher.json are first guesses. Tune them on contact sheets.config/camera.json defines the only camera. It is anchored at 12.9716 N, 77.5946 E, tilted 45°, turned 15°, at 0.293 m per pixel, the same as tiny.london and isometric.nyc.render/main.js), so neighbouring shots share edges exactly.src/blr/camera.py builds the same camera matrix in Python (WGS84 → ECEF → camera frame) and defines the map projection: project(lat, lon, h) gives canvas pixels and unproject goes back. Search, OSM water masks and the planner all go through it.tests/test_camera.py checks camera.py against 3d-tiles-renderer's own maths. blr.render also checks it against the live browser before it renders anything.runs/<name>/render_log.jsonl.The renderer setup follows Andy Coenen's isometric-nyc (MIT), and the method follows Boris Starkov's tiny.london. Imagery is derived from Google Photorealistic 3D Tiles, so keep Google's attribution (saved per run in attributions.json).