Inspiration
Toronto is building a lot of housing, and that's a good thing. But "a new 30-storey building with hundreds of homes" is hard to picture when it's going up on your street. Planning documents and architectural drawings don't tell you what you actually want to know:
- What will the skyline look like from my street?
- Will the park still get afternoon sun?
- Will my streetcar get more crowded?
- What would help transit keep up once people move in?
These questions are connected. New housing changes both the shape of a neighbourhood and how many people share its streetcar. We wanted residents to be able to see those changes before the buildings are finished, so they can show up to community discussions with clearer questions and real evidence.
What it does
Urbanova lets you explore a real Toronto neighbourhood and see what proposed housing could change, from the view on your street to your morning commute.
Our starting area is the westbound 505 Dundas streetcar, from Broadview Avenue to TMU Station at Yonge and Dundas: nine stops and three real development proposals at 239, 500 and 761 Dundas Street East.
Buildings and the skyline
Walk the neighbourhood at street level or fly above it. Turn the proposed buildings on and off to see their height and scale next to what's already there. Proposals are shown as simplified shapes, so residents can distinguish existing buildings from proposed ones.
Sunlight and shadows
Choose from four seasonal dates and preset times of day to compare shadows with and without proposed buildings. See where a new building could block sun, or add some welcome summer shade, and how that changes through the seasons.
Your streetcar commute (the core of Urbanova)
Our simulation follows individual passengers and streetcars along the corridor. You can see waiting times, crowding, and how many people get left behind when a full streetcar pulls up. It also shows something averages hide: a building further up the line can make your stop worse, because more people board before the streetcar reaches you.
Comparing transit improvements
Keep the housing the same and compare unchanged service with more frequent streetcars, alongside estimated operating costs and vehicle needs. The backend also supports comparisons with a transit priority lane or both improvements, using explicit assumptions about costs, fleet availability and when upgrades could be ready.
A typical visit
- Find a familiar place: a proposal near home, a park, or your usual stop.
- Toggle the new buildings and check sunlight at a preset season and time.
- Run simulations and see how waiting and crowding change at your stop.
- Compare service frequency, with its costs and assumptions.
- Use the results and stated limitations to bring clearer questions into the discussion.
How we built it
Frontend: React and TypeScript, with Mapbox rendering the 3D neighbourhood and building data derived from City of Toronto sources.
Simulation: a Python transit simulator that advances in one-second steps and records passenger and streetcar events: arriving at stops, boarding, getting off, and being left behind when a car is full.
Backend: an Express API with PostgreSQL storing scenarios and results.
From new homes to new riders
We turn each proposal into potential commuters with an explicit chain of assumptions:
Potential commuters = round(net added units × occupied share × residents per occupied unit × trips per resident in the simulated window × share considering the 505 corridor)
We then sample workplace destinations using 2021 Census workplace counts and apply simplified walking, subway and streetcar rules to determine who uses the westbound 505. The workplace weights come from real data; the sampled destinations and travel choices are model assumptions, not observed commutes for each building.
Who fits on the streetcar
When a streetcar serves a stop, we work out how much room is left after passengers get off:
Available capacity = vehicle capacity − passengers still onboard after alighting
and how many waiting passengers can't get on:
Denied boardings = max(0, waiting passengers − available capacity)
Anyone who doesn't fit stays in line for the next car. Run that across every stop and every streetcar and you can watch crowding build up along the line. The model also includes stop queues and a no-overtaking rule, so one delayed streetcar can hold up another.
Dealing with uncertainty
The simulator supports repeated runs with different random seeds, and the backend comparison workflow tests low, central and high demand. This lets us explore a range of outcomes instead of relying on one number. Housing stays fixed across transit options, so the comparison isolates the service change.
Research partner
We're building a Gemini/Papiers research partner for questions like "Why does my stop get worse when the new building is farther away?" The prototype tests bounded hypotheses by running the simulator and explains what the results do and don't support. Human context and service constraints can steer the next test. Papiers research reads depend on a configured connection.
Challenges we ran into
Missing data. We didn't have observed passenger boardings for each stop and time of day. Occupancy and travel habits are uncertain too. Instead of treating these as known values, we used explicit assumptions and tested a range of values.
Choosing the study area. Our first choice of corridor didn't have enough downstream stops to show the "left behind further down the line" effect, which is the whole point. We extended it to nine stops toward downtown to fix that. Nearby routes and transfers are represented only approximately or left outside the simulated corridor.
Connecting everything. Getting the 3D map, the simulation event logs and the comparison views to read the same data, while four people built different pieces in parallel, took much more coordination than we expected.
Accomplishments that we're proud of
- A simulation that follows individual passengers and streetcars, not just averages.
- A full 3D replay where you can watch streetcars move, people walk to stops, and crowding change, using recorded simulation events and mapped routes.
- Building it around real Toronto data and three real proposals, not a made-up city.
- Being honest about uncertainty by recording sources, assumptions and limitations alongside the model inputs and backend comparisons.
What we learned
Getting the math right was only half the job. The other half was making the results understandable to someone who isn't a transit engineer.
We also saw how tightly housing and transit are tied together, and how easily an average hides the people stuck at the back of the line.
Our biggest takeaway: tools like this should help people question predictions, not blindly trust them.
What's next for Urbanova
- Finish and validate the research partner, so residents can ask "why" questions and get answers backed by real simulation runs.
- Check our results against real TTC observations.
- Add more corridors, the other direction, and simulated transfers between routes.
- Make it easy for anyone to find their own stop and save a shareable brief.
Limitations
Urbanova is an exploratory prototype, not a TTC forecast. Results show what could happen under the assumptions we chose. Workplace sampling and travel choices are simplified, and stop dwell times are sampled rather than calculated from passenger counts. The 3D buildings are simplified, and the shadow comparison models sunlight on flat ground at selected seasonal dates and times; it doesn't predict temperature or comfort. Some comparison and export capabilities currently exist in the backend rather than the main interface.
Data sources
- City of Toronto Development Applications
- City of Toronto 3D Massing (building footprints and heights)
- TTC Routes and Schedules (GTFS)
- OpenStreetMap (walking network)
- Statistics Canada 2021 Census (workplace and commuting data)
Urbanova: see what new housing could change in your neighbourhood.
Built With
- fastapi
- gemini-api
- geopandas
- google-gemini
- gtfs
- javascript
- mapbox-gl-js
- numpy
- openstreetmap
- pandas
- python
- react
- react-three-fiber
- three.js
- typescript
- vite
- webgl
Log in or sign up for Devpost to join the conversation.