The idea came from tiny.london and Pixel Berlin. Both show a whole city as one large drawing, seen from the same oblique angle. I wanted the same for Prague, with the Old Town, the castle and the Vltava with its bridges and islands.
Both of those maps were made by having an image model redraw a photorealistic 3D city tile by tile, so I started the same way.
1 The AI route
The process has four steps. First I rendered a pilot area of central Prague from a photorealistic 3D model. The camera is orthographic, tilted 45° and turned 15°, at about 0.29 metres per pixel. The renders are square tiles that fit together exactly.
Second, Nano Banana Pro redrew a selection of these renders in the target style. The prompt describes only how to draw: thin dark outlines, two or three flat tones per surface, no gradients, the colours and shadows of the render kept, nothing added or removed. Eight drawings I was happy with went along with every further request as style references, to keep the style consistent.
Third, the pairs of render and drawing became training data for a LoRA for Qwen-Image, an open image-editing model. Training on 90 pairs took one night on a rented GPU and cost a few dollars.
Fourth, the trained model redraws the whole city tile by tile. The tiles overlap, so there are no visible seams. This step runs on my own graphics card.




Nano Banana kept the geometry of the render well. The LoRA picked up the style from 90 examples.
More drawings by Nano Banana Pro. Click an image to see it full size and switch between the drawing and the render it was made from.








2 Problems
The models sometimes change things that are in the render. In one checkpoint of the LoRA, the Vltava turned into a lawn.




Errors like this can be detected by comparing the water with OpenStreetMap and redrawing the tile, but that is another step in an already long process. Three other things weighed more.
Time. One tile takes about half a minute on my card and the whole city needs thousands of them, so a full run takes days. Any change of style means running it again.
Static result. The output is one large image. Night, a moving sun, trams or clickable buildings would each need separate work on top of it.
Licences. The 3D model I rendered from cannot be redistributed freely, and the Qwen-Image licence allows only non-commercial use.
3 The open-data route
The second version uses no image model. The browser draws the city from open data in a style a computer can draw well: flat-coloured buildings, one sharp shadow, trees as round crowns.
IPR Praha, the city's planning institute, publishes a 3D model of every building and bridge in Prague, including roof details such as chimneys, dormers and towers. It also publishes a terrain model, an orthophoto and a map of greenery, all under CC BY 4.0. Streets, parks, water and place names come from OpenStreetMap.
Scripts convert this data into compact binary files, one per square kilometre, and the browser loads only those in view. Roof colours are sampled from the orthophoto, wall colours from OpenStreetMap and the 3D mesh. The first working version took one day. It uses the same camera as the AI route, so the two can be compared view by view. The map now covers about 60 km² and the first view loads in under two seconds.
The pixel-art mode renders the same 3D scene at half resolution, snaps each pixel to a limited palette and draws dark outlines where the depth changes sharply. The camera moves in whole pixels, which stops the image from shimmering while panning. The switch at the bottom right changes the style without moving the view.
4 What the live map adds
Because the scene is drawn live, it can change over time. These were added step by step:
Light and time. A default daylight setting, a night mode, and a live mode with the actual position of the sun over Prague and a time slider. At night windows light up, street lamps light the streets, and the castle, Charles Bridge and other landmarks are floodlit.
Trams and boats. Trams follow the PID timetable at their real speed on the real tracks, including over and under bridges. Boats sail on the Vltava between the weirs and others are moored along the embankments.
Details. Windows on all facades, trees made of several rounded crowns, and information about landmarks: hovering over a notable building outlines it, and clicking it opens a panel with a description and a photo from Wikimedia Commons.
St Vitus Cathedral. This was the one building where the IPR model was not detailed enough: its Gothic towers and pinnacles came out as plain cones. Projecting an AI drawing onto the model looked patchy, so the cathedral was built in Blender as a stylised model with flying buttresses, the west front and the helmet of the main tower. It uses flat colours and real geometry, so it is lit and casts shadows like the rest of the city.
5 Comparison
| AI route | Open data | |
|---|---|---|
| Look | Detailed, hand-drawn texture | Simpler, clean and consistent |
| Accuracy | Mostly faithful, occasional invented details | Matches the data |
| Build time | Days for the whole city | Minutes to rebuild the data |
| Changes | New style means redrawing everything | Change a colour and reload |
| Interactivity | Static image | Day and night, trams, boats, landmark information |
| Licences | Restricted input and model | Open data and open-source libraries |
The AI drawings have more texture than flat shapes can give. A combination is possible: the live map everywhere, with pre-drawn tiles for the main landmarks. For a map that changes with the time of day and can be extended easily, I went with open data.
Explore the map →Data and thanks
- Buildings and bridges, terrain, orthophoto, greenery: © IPR Praha, CC BY 4.0
- Streets, land use, water, place names: © OpenStreetMap contributors, ODbL
- Tram timetable: PID open data, CC BY 4.0
- Landmark texts and facts: Wikipedia (CC BY-SA 4.0), Wikidata (CC0); photos: Wikimedia Commons
- AI route: renders from Google Photorealistic 3D Tiles, drawings by Nano Banana Pro, LoRA trained for Qwen-Image
- Software: three.js, Blender; Press Start 2P typeface by CodeMan38