# Leuven cafe decision map: method and sources

Published snapshot: 7 October 2026. Independent research exercise by Data with Sina, developed with AI assistance.

## Decision

Where should a hypothetical new cafe investigate a location? The tool compares resident demand, mapped competition and uncalibrated Huff-model scenarios. It does not identify vacant premises or forecast profitability.

## Observations

- Statbel 2025 population on the NEW 2025 sector geography: 104,906 residents in Leuven (municipality 24062).
- 134 polygon sectors match population data. The unmatched code 24062ZZZZ contains 145 residents without a locatable sector. Spatial modelling therefore covers 104,761 residents. Zero-population sectors remain on the map but do not contribute demand.
- OSM amenity=cafe snapshot on 7 October 2026: 80 mapped venues inside Leuven plus 18 nearby competitors within the source bounding box. Two shop=coffee retail stores and one same-name node within 25 metres of an existing node are excluded. The reviewed output does not retain contributor usernames or IDs.
- Café coverage is not a business census. Closed, missing or misclassified venues may affect results. Restaurants, pubs and other substitutes are not comprehensively represented.
- OSM roads, parks, waterways and place labels form the self-contained vector background. No remote map tiles are used.

## Model

Huff scenarios use the published `huff` Python library, version 1.9.13. For each origin i and destination j, utility is A_j / d_ij^beta. Probability is that utility divided by the sum across existing cafes and one new cafe. Resident-weighted choice share is sum(population_i * probability_i,new) / total located population.

- Origin: one interior representative point per populated sector (130 origins).
- Existing cafe attraction: 1 for every venue, an assumption rather than a measured rating.
- Candidate attraction: 0.5, 1 or 2; exponent on attraction is 1.
- Distance exponent: 1, 2 or 3, not calibrated to observed visits.
- Distance: projected straight-line metres in EPSG:31370, floored at 100 m. It is not a walking route or travel time.
- 351 candidate points on a 400 m grid inside populated Leuven sectors. Each point is tested independently with one hypothetical new cafe, not all candidates at once.
- Gap shading: sectors at or above median resident density with no more than three mapped cafes within 750 m of their representative point, excluding sectors without tested candidates. This is screening, not a measured service gap.
- Shortlist: candidate points with at most three nearby mapped cafes and sector density at or above the median, ranked by the Huff scenario; selected points remain at least 800 m apart.
- Stability statement: whether the selected point stays in the top quarter under each of the three distance exponents, holding candidate attractiveness constant. It is not a confidence interval or validation score.
- Resident layer: registered population / sector area in square kilometres.
- Competition layer: number of mapped cafes within 750 m of each sector's representative point.

The model is conditional on choices among included venues and the candidate, without an outside/non-purchase option. Percentages are modelled choice shares, not observed visits, customers or sales. Geometry simplification is used for display only; distances and inclusion tests use original projected boundaries.

## Checks

All geographic sector IDs match population IDs except the explicitly unlocated code. Located plus unlocated population reconciles with 104,906. Coordinate systems are checked before reprojection. Model probabilities are finite, bounded from zero to one and sum to one for every origin. Baseline weighted flows sum to located population. Increasing candidate attraction never lowers its share. All nine scenarios have 351 candidate results.

## Material limitations and next test

Students not registered in Leuven, commuters, visitors, observed foot traffic, actual cafe quality, route barriers, capacity, rent, land use and planning permissions are not measured. Representative points and coarse grid cells can produce artificial concentration effects. Check shortlisted streets and businesses in person before treating a low-competition area as a genuine gap.

The most valuable next evidence is an audit of cafe coverage and simple pedestrian counts at a few candidate locations. Improve that evidence before adding a more detailed model or a larger interface.

## Reproduce

`source-manifest.json` contains exact public request URLs, Overpass queries, snapshot dates and SHA-256 hashes. Raw public downloads are retained in the local working research folder; the public reviewed JSON is the processed snapshot. `prepare-data.py` joins original Statbel data, transforms coordinates with pyproj and shapely, and runs huff. It requires Python with huff 1.9.13, pyproj and shapely. `fetch-sources.ps1` performs bounded public downloads. Refreshes are manual; a published snapshot does not refresh automatically.

## Sources and attribution

- Population: https://statbel.fgov.be/en/open-data/population-statistical-sector-12
- Boundaries: https://statbel.fgov.be/en/open-data/statistical-sectors-2025
- OSM data and licensing: https://www.openstreetmap.org/copyright (Open Database Licence)
- Huff package: https://github.com/geowieland/huff_official
- Method: https://pro.arcgis.com/en/pro-app/3.5/tool-reference/business-analyst/understanding-huff-model.htm
- Leaflet 1.9.4 and Turf 7.2.0 provide map rendering and browser geospatial selection; their licence notices are included with the browser assets.

## Visitor experience revision (7 October 2026)

Two views: explore cafes and find possible gaps. The map clusters nearby pins. Cafe insights count other venues only and show the nearest alternative, with branch-aware search. Model percentages and parameters are optional details. The Onan records were reviewed against https://onan.be/nl/ (which describes two nearby locations) and retained because their addresses differ. Summaries describe competitive location context, not observed business performance.
