Skip to content

Gravity Model

The Gravity Model estimates the total potential flow of diners toward this location from population rings at increasing distances. Think of it as: how many person-visits per day could realistically arrive here given population, income, and distance?

Unlike the Huff model (which calculates our market share), the Gravity model measures the raw demand pipeline. Multiply flow by Huff captureProb to get actual covers.

flow_zone = k × Oᵢ × Dⱼ / distM^β

Where:

  • Oᵢ = origin mass (zone population × income match × dining frequency)
  • Dⱼ = destination attractiveness (effective area × cuisine score × income match)
  • distM = midpoint distance of zone in metres
  • k = scaling constant (varies by floor area)
  • β = distance decay exponent (varies by service model / price band)
k = max(0.0008, 0.003 - (floorArea - 300) × 0.000002)

Examples: 300 sqft → k=0.003; 800 sqft → k=0.002; 1200 sqft → k=0.0014.

Larger venues get a lower k to prevent unrealistic flow numbers — physical capacity caps actual throughput.

effectiveArea = max(400, floorArea)
cuisineScore = min(2, effectiveArea / 500)
Dⱼ = effectiveArea × cuisineScore × incomeMatch

The effective area floor of 400 means even small budget restaurants (e.g. a 200 sqft cha chaan teng) get reasonable gravity pull — they attract as much foot traffic as a larger one; they just can’t serve the overflow.

Price bandLow income (<18–22K)Mid incomeHigh income
Budget1.21.00.8
Mid0.81.01.0
Premium0.71.01.2
High-end0.51.01.3

Gravity Beta (Distance Decay within Zones)

Section titled “Gravity Beta (Distance Decay within Zones)”

Separate from the Huff beta — this controls how steeply flow falls off within each ring:

Service / pricegravityBeta
Delivery0.8
Takeaway0.7
High-end0.6
Premium0.7
Mid0.8
Budget0.9

For delivery and takeaway, zones within 1400 m (delivery) or 600 m (takeaway) get an additional effectiveBeta × 0.7 boost.

ZoneMidpoint usedPrimary data source
0–400 m (5 min walk)200 mSTPU census zone cumulative ring
400–800 m (10 min walk)600 mSTPU ring differential
800 m–2 km (transit)1400 mSTPU ring differential
2 km+ (destination)3500 mSTPU 5 km ring minus 2 km ring

When STPU data is unavailable, falls back to density × π × r² × coverage factor.

Zero-population zones: If a ring has pop = 0, flow = 0 is returned (previously returned flow = 1).

Minimum floor: Zones with pop > 0 always return at least flow = 1.

  • Population: Census 2021 STPU (211 zones), aggregated into distance rings
  • Income: STPU weighted median household income
  • Dining frequency: constant 15% daily dine-out rate (HK average)
estimatedFlowMeaning
5,000+Dense urban core with high foot traffic potential
1,000–5,000Typical urban neighbourhood
200–1,000Suburban or low-density area
< 200Remote or very low-density site
  • Assumes uniform population distribution within each ring (STPU zones reduce this error significantly)
  • Dining frequency (15%) is a Hong Kong average — varies by day of week and season
  • No distinction between lunch and dinner demand patterns
  • Worker/commuter population not separately modelled here (handled in KPI estimates)
DateChange
2026-03-25Zero-population rings now return flow=0 instead of flow=1
2026-02-10Initial implementation with STPU ring data integration