About This Project

How we built an interactive intelligence map of Indian cuisine across Greater Melbourne, using open government data, place APIs, and census demographics.

1,437
Restaurants
361
SA2 Areas
3
Data Sources
40%
Peak Indian Pop.

Data Sources

ABS Census 2021 — Demographics
Government
The Australian Bureau of Statistics Census 2021 provides population demographics at the SA2 (Statistical Area Level 2) geographic level. We extract three key datasets from the General Community Profile DataPack for Victoria.
Coverage: 361 SA2 areas across Greater Melbourne
Format: CSV in ZIP DataPack (~13 MB)

Fields Used

SA2 Boundaries

SA2 polygon boundaries are fetched from the ABS ArcGIS REST API at geo.abs.gov.au, filtered to the Greater Melbourne GCCSA region. Geometries are simplified (Douglas-Peucker tolerance ~100m) for web rendering.

Google Places API — Restaurant Supply & Ratings
API
The Google Places API (New) provides the most comprehensive restaurant data, including ratings and review counts. We search for "Indian restaurant" across 30 key Melbourne suburbs, covering both inner city and outer growth corridors.
Coverage: 30 suburbs, ~414 unique restaurants
Max per suburb: 20 results (API limit)

Fields Used

Suburbs Searched

Dandenong, Clayton, Truganina, Tarneit, Point Cook, Glen Waverley, Craigieburn, Werribee, Springvale, Footscray, Melbourne CBD, Epping, Berwick, St Albans, Caroline Springs, Hoppers Crossing, Deer Park, Sunshine, Narre Warren, Cranbourne, Pakenham, Box Hill, Preston, Reservoir, Melton, Richmond, South Yarra, Roxburgh Park, Wyndham Vale, Williams Landing.

Foursquare Open Source Places — Restaurant Supply
Open Data
Foursquare's Open Source Places dataset on HuggingFace contains ~100M+ places globally. We download only the Australian Parquet partitions (files 98 & 99, ~240 MB total), filter to the Melbourne bounding box, and identify Indian restaurants by name keywords.
Coverage: ~1,060 Indian restaurants in Greater Melbourne
Format: Parquet via HuggingFace Datasets API

Fields Used

Filtering Method

Indian restaurants are identified by matching name keywords (indian, curry, dosa, tandoori, biryani, masala, sri lanka, nepal, etc.) and then filtered to exclude non-restaurant places (grocery stores, taxis, salons) using both category IDs and name exclusions.

Dataset: foursquare/fsq-os-places
License: Apache 2.0
City of Melbourne CLUE — CBD Restaurants
Government
The Census of Land Use and Employment (CLUE) dataset from Melbourne's Open Data portal provides official business registration data for cafes and restaurants within the City of Melbourne municipality (CBD and immediate surrounds only).
Coverage: ~36 Indian restaurants in CBD area
Limitation: City of Melbourne LGA only (not Greater Melbourne)

Fields Used

Methodology

1
Fetch SA2 Boundaries
Download 361 SA2 polygon boundaries for Greater Melbourne from the ABS ArcGIS REST API. Simplify geometries for web display.
2
Join Census Demographics
Download the ABS Census 2021 DataPack for Victoria. Extract Indian-born population (G09G), total population (G01), and median income (G02). Join to SA2 boundaries by SA2 code. Compute india_pct = india_born / total_pop * 100.
3
Collect Restaurant Data
Fetch Indian restaurants from three sources: Foursquare (Parquet download + keyword filter), Google Places API (text search across 30 suburbs), and CLUE (Melbourne Open Data API). Deduplicate across sources by name + location proximity.
4
Cuisine Classification
Each restaurant is classified into a sub-cuisine by keyword matching on its name: South Indian, North Indian, Sri Lankan, Nepalese, Bangladeshi, or General Indian.
5
Spatial Join & Gap Analysis
Restaurants are spatially joined to SA2 polygons to count restaurants per suburb. An opportunity (gap) score is computed for each SA2 area.

Opportunity Score Formula

opportunity_score = (
  (india_pct / max_india_pct) * 0.4 +
  (median_income / max_income) * 0.2 +
  (1 - supply_per_10k / max_supply) * 0.4
)

Where supply_per_10k = number of Indian restaurants per 10,000 Indian-born residents in that SA2. A high score indicates high Indian population, decent income, but few restaurants — a market opportunity.

Gap Classification

Demand Score (per restaurant)

demand_score = rating * log10(review_count + 1)

This normalises for both rating quality and volume. A 4.5-star restaurant with 500 reviews scores higher than a 5-star restaurant with 3 reviews.

Deduplication

Restaurants appearing in multiple sources are deduplicated by matching on name (case-insensitive) and coordinates (rounded to 3 decimal places, ~100m). When a duplicate is found, the Google Places version is preferred (it has ratings and reviews), followed by Foursquare, then CLUE.

Limitations

Tech Stack

Source Code

The data pipeline (prepare_data.py) and dashboard source are open source. The pipeline fetches live data from all sources and generates the data/dashboard_data.js file that powers the map.

Disclaimer: This is an independent data visualisation project for educational and analytical purposes. It is not affiliated with the Australian Bureau of Statistics, Google, Foursquare, or the City of Melbourne. Restaurant data may be incomplete, outdated, or contain errors. Do not use this data as the sole basis for business decisions.