Fujimod
Try your camera firmware in the browser and build Fujimod SD boot files.
Bengaluru as one isometric map. Zoom from the whole city down to single streets, and find any place or metro station.
LifestylePython · JavaScriptGitHub @Rithvik1709OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full 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).