Inspiration
Cities are not experienced the same way by everyone.
A street that feels convenient for a tourist might be difficult for a wheelchair user. A route that works well during the day might feel completely different after dark. A parent pushing a pram may care about crossings and kerb ramps in ways that another person does not.
That inspired Blockprint.
Instead of giving every block one universal score, we wanted to show how the same city changes depending on who is experiencing it.
Same blocks, same data, ten different lives — the city doesn't change; who you are does.
Blockprint explores Sydney's inner city through ten personas, including wheelchair users, parents with prams, tourists, people with low vision and people travelling after dark.
What it does
Blockprint scores more than 2,400 city blocks across 14 measured characteristics using only open data.
Switching personas instantly changes how the city is scored because each persona values different characteristics differently. The seven most contrasting personas are available directly from the main interface.
Users are not locked into our assumptions either. Every scoring weight can be changed manually, and all 2,400+ block scores recompute instantly in the browser.
Clicking any block opens a detailed scorecard showing its overall score, subscore breakdown, main issue for the current persona, and the improvement that would create the largest score gain.
We also placed 26 historic and cultural landmarks across the map, using Wikipedia data to connect the current city with the stories behind its places.
Parkland blocks are excluded from direct scoring because their unusually high scores made them statistical outliers. Instead, parks contribute to the green-space score of surrounding blocks.
How we built it
Blockprint has two main parts: a Python 3.12 data pipeline and a fully client-side React frontend.
Our preprocessing pipeline uses GeoPandas and Shapely for spatial joins, clipping and metre-accurate distance calculations using the GDA2020 projection.
We use pandas to process Transport for NSW GTFS data, including millions of stop-time rows, and reduce it into useful per-stop information such as wheelchair accessibility and late-night service.
One-time dataset downloads are handled with requests and cached in the repository so the application does not need to repeatedly fetch external data.
The frontend is built using React 19, TypeScript and Vite.
For visualisation, we use deck.gl and WebGL to render more than 2,400 extruded score prisms and approximately 20,000 OpenStreetMap buildings at 60fps, including animated transitions when switching personas.
MapLibre GL provides the underlying vector basemap, which we customised to match the visual identity of the project.
All scoring happens directly in the browser. Each block score is calculated as a weighted combination of the 14 characteristics, meaning changing personas or adjusting weights requires no server request.
Our data sources include:
- ABS Mesh Blocks and LGA boundaries
- Transport for NSW GTFS
- OpenStreetMap via the Overpass API
- National Public Toilet Map
- Wikipedia REST API
From these sources we measure features such as public transport accessibility, crossings, kerb ramps, tactile paving, lighting, footpaths, benches, shops, parks, buildings and accessible toilets.
Wikipedia landmark images and summaries are fetched at build time, allowing the deployed app to remain offline-capable.
The intervention engine
We also wanted Blockprint to do more than highlight problems.
For every block, the pipeline asks:
If the council could build exactly one thing here, what would help most?
It tests five possible interventions:
- Kerb ramp
- Tactile paving
- Controlled crossing
- Bench
- Accessible toilet
For each candidate, we simulate how adding that feature would change the block's subscores and calculate the resulting score improvement for the persona that intervention is intended to support.
For example, a kerb ramp is evaluated through the wheelchair-user persona, while tactile paving is evaluated through the low-vision persona.
The intervention producing the largest improvement is stored as the recommended fix. We then attach the nearest street name so the result can read like a practical work order rather than an abstract statistic.
This means Blockprint can show not only where a block performs poorly, but also what could improve it most.
Challenges we ran into
- The bug our own map caught: Centennial Park scored 0 for green space. Digging in revealed two real issues — big parks are mapped as OSM relations (we'd only fetched ways), and a filename mismatch meant green space had silently been scored against no data at all. The 3D view made a silent data bug visible in seconds.
- Parks aren't homes: scoring parkland like residential blocks produced nonsense, so we taught the pipeline ABS block categories and left parks unscored.
- Honest modelling under missing data: before our GTFS key arrived, no stop could be verified step-free — we shipped the OSM fallback and swapped in real flags later.
What we learned
Accessibility isn't one number — the same block genuinely ranks opposite ways for different people. And our optimizer surfaced a real finding: tactile paving is inner Sydney's most systematically missing accessibility feature, topping the highest-impact-fix list on most blocks.
What's next
Cycling infrastructure as a full subscore, council-area comparisons, and pointing the same pipeline at any city in Australia — the data is all open; only the bounding box changes.
Built With
- abs-census-data
- css
- geojson
- geopandas
- github-actions
- maplibre-gl
- numpy
- openstreetmap
- overpass-api
- pandas
- python
- react
- transport-for-nsw
- typescript
- vite
- wikipedia-api
Log in or sign up for Devpost to join the conversation.