Wrocław in 3D over a single weekend - the wro3d.pl case study
How a photorealistic 3D map of Wrocław with a voice guide was built in one weekend: Google 3D Maps, MapLibre, an ElevenLabs voice clone and lessons from working with AI.
An interactive, photorealistic 3D map of Wrocław with a virtual tour and a voice guide - built in a single weekend, with no framework and no backend. This exercise project taught us more about working with Google APIs, voice cloning and AI-assisted testing than many commercial builds. You can explore the result at wro3d.pl; below is what worked, what surprised us, and the lessons we are taking into client projects.
The starting point
The idea was simple: a 3D map of Wrocław you can stroll around without leaving the browser. Twelve landmark locations - from the Market Square, through Ostrów Tumski, to the Centennial Hall - with a virtual tour that guides you through the city on its own.
No framework, no backend, no build process. Plain HTML, CSS and JavaScript - a site you can upload to any hosting over FTP. The whole project was built in a duo with AI (Claude Code) over one weekend.

Version one: the vector map
We started with a fully open-source stack: MapLibre GL JS plus free vector tiles from OpenFreeMap (OpenStreetMap data). The 3D buildings come from extruding footprints in the buildings layer - each block's height comes straight from OSM data, so Sky Tower genuinely towers over the city at its full 212 metres.
On top of that: a night mode, Esri satellite imagery as a hybrid base layer, a camera tilt slider and a place search built on Nominatim. Zero API keys, zero costs, full control.
That version still lives at wro3d.pl/mapa.html - as a lighter alternative and a fallback.
Plot twist: photorealistic 3D and the EEA trap
Extruded blocks are impressive, but the real "wow" comes from Google's Photorealistic 3D Tiles - the same photorealistic city models you know from Google Earth. Wrocław is fully covered: real tenement facades, cathedral details, trees, bridges.
And here came the first serious lesson. After creating an API key and connecting billing - a 403 error:
"Satellite tiles and 3D tiles are not available for your account and region."
It turned out that as of July 2025 Google has switched off Photorealistic 3D Tiles (Map Tiles API) for European Economic Area accounts. No application form, no waiting list - it is simply gone.
Fortunately, there is an official door for Europe: "3D Maps" in the Maps JavaScript API, i.e. the gmp-map-3d component. The same photorealistic tiles, just served through a different interface that is allowed in the EEA. The migration required rewriting the camera logic, but we lost nothing functionally.

The takeaway for commercial projects: Google API availability can depend on your billing region and can change overnight. Your map layer should have a fallback - ours is the vector version.
A camera that gives the tour
The heart of the project is the virtual tour: the camera flies to a landmark and then slowly orbits around it (a full circle takes about 2 minutes) while the narrator tells the story of the place. When the recording ends - a flight to the next stop.
Two implementation details worth sharing:
- Google's built-in orbit function (flyCameraAround) proved unreliable - the rounds parameter is deprecated and ignored, so the "orbit" ended after two seconds. The fix: our own requestAnimationFrame loop that smoothly increments the camera heading. Simpler, predictable, with full control over speed.
- Same with camera tilt: Map3DElement ignores direct assignment of the tilt property - only flyCameraTo works. You only discover these things by testing, not by reading the documentation.
The tour controls look like a media player remote: a floating bar at the bottom of the map with start, pause (resuming narration exactly where it stopped), skipping between stops and mute. On a phone the side panel hides automatically, so the bar is the only interface you need.
Romuald's voice from ElevenLabs
The most "human" element of the project came together the fastest. The descriptions of the twelve landmarks are read by the voice of Romuald - C3S co-founder - cloned in ElevenLabs. A few minutes of sample audio were enough to generate twelve natural-sounding narrations that Romuald never actually read out loud.
Wiring the audio to the map is trivial: MP3 files (mono, about 1 MB each) named after landmark identifiers, a single Audio object and the ended event driving the rhythm of the tour - the next stop only comes when the narrator finishes. All the "magic" sits in the quality of the voice, not in the code.
The details that make the difference
- The Wrocław coat of arms (an SVG from Wikimedia Commons, public domain) in the header, favicon and OG graphic - a small thing, but the site instantly looks like its own.
- The Open Graph image is a real screenshot of the photorealistic map (a bird's-eye view of Ostrów Tumski) with branding overlaid - generated by a Playwright script, so it can be refreshed with a single command after any major change.
- SVG icons in the Lucide style instead of emoji - a consistent visual language for the panel, while keeping emoji on map markers, where colour improves readability.
- Cache busting through file versioning - a banality that saves hours of explaining "just refresh with Cmd+Shift+R".
- A cost fuse: daily request caps in the Google console set so that exceeding the free tier is physically impossible - at worst, the map stops loading.
Testing without clicking
Every feature - the orbit, pausing the tour, hiding the panel on mobile, navigating between stops - was verified automatically with Playwright: a script opens the page, clicks, queries the camera state and asserts the result. It was the tests that caught both Google's dead orbit and a subtle race condition in which a stale animation listener could quietly kill a freshly started tour.
In a "weekend project" it is tempting to skip tests. Don't - half of the bugs we found were invisible to ordinary clicking.
Summary
- Build time: one weekend
- Stack: HTML/CSS/JS (zero frameworks), Google Maps 3D, MapLibre GL, ElevenLabs, Playwright
- Backend: none - static hosting
- Running costs: zero at up to ~1,000 sessions per month (Google's free tiers)
- The result: wro3d.pl
An exercise project, but with production-grade lessons: APIs can be regionally capricious (have a fallback), documentation can be stale (test, don't trust), and a cloned ElevenLabs voice raises the bar of what can be done in a weekend by several levels.
Have an idea for a similar tool for your city, product or business? Get in touch - we build things like this every day, not just on weekends.
Let us turn it into a working app.
Free consultation and a quote within 48h - no obligations, with clear ranges.