هذه الصفحة غير مترجمة بعد. أنت تقرأ النسخة الإنجليزية.

Methodology

The formulas behind MapDove's models: Huff gravity, calibration, cannibalization, trade areas, MCDA suitability, catchment aggregation and cross-shopping.

This page documents the models exactly as they are implemented. Every SDSS result in MapDove can be reproduced from these formulas and the data described in Demo data. Distances are great-circle distances between points in kilometers; all models run on the city’s hexagonal grid (cells of about 0.8 km²).

Notation

Symbol Meaning
i a hex cell (origin of demand)
j, k stores of the category being modeled
d_ij distance from the centroid of hex i to store j, in km
A_j attractiveness of store j
λ distance-decay exponent of the category
R trade radius of the category, in km
D_i demand of hex i
P_ij probability that demand in hex i goes to store j
E_j expected (modeled) demand captured by store j

Demand

D_i = population_i + 0.4 · daytime_pop_i

Residents count fully; the daytime population (workers, students, visitors present during the day) counts at 40% to reflect that it drives a share of trips without being the household’s main shopping base.

Attractiveness

A_j = (sqft_j / base_sqft)^0.7 · brand_strength_j
  • base_sqft — typical size of the category (see the table below).
  • 0.7 — returns-to-scale exponent: larger stores are more attractive, with diminishing returns.
  • brand_strength — brand multiplier (fictional chains 0.9–1.2; independents 0.8–1.15; candidate stores 0.6–1.5 as entered).

Huff gravity model

For each hex i, only stores within the trade radius (d_ij ≤ R) are considered:

U_ij = A_j / max(d_ij, 0.4)^λ

u0   = 1 / (0.6 · R)^λ

P_ij = U_ij / ( Σ_k U_ik + u0 )
  • U_ij — utility of store j for residents of hex i. The 0.4 km distance floor prevents a store inside a hex from receiving infinite utility.
  • u0 — utility of the outside option (shopping in another category, online, outside the city, or not at all). It equals the utility of an average-attractiveness store at 60% of the trade radius. Hexes far from every store therefore send most of their demand to the outside option, and probabilities in a hex sum to less than 1.
  • Σ_k U_ik — sum over all stores within R of hex i.

Expected demand captured by store j:

E_j = Σ_i P_ij · D_i

Calibration and forecast

E_j is in population units. A single scaling factor per city and category converts it to visits:

k = Σ_j V_j / Σ_j E_j
  • V_j — observed average daily visits of existing store j over the last 90 days of data.
  • Sums run over all existing stores of the category in the city.

For a candidate store c (added to the store set with its own A_c):

predicted_daily_visits  = k · E_c
predicted_annual_visits = 365 · k · E_c
market_share            = E_c / Σ_j E_j_after        (all stores, candidate included)

Cannibalization

The model is evaluated without and with the candidate:

Δ_j   = k · (E_j_after − E_j_before)
Δ%_j  = 100 · (E_j_after − E_j_before) / E_j_before
total_cannibalized_daily = −Σ_j Δ_j

The ten stores with the largest losses (losses below 0.5 visits/day omitted) are reported. See Cannibalization.

Trade areas

Flow from hex i to store j is F_ij = P_ij · D_i, and the hex’s share is:

s_j(i) = F_ij / Σ_i' F_i'j

Hexes are sorted by s_j(i) descending and accumulated. A hex is included while the cumulative share before it is below the cut-off:

Trade area Cut-off
Existing place (/places/:id/trade-area) 85%
Candidate in a Huff forecast 80%

Summary demographics are sums (population, households) or population-weighted means (income, age, education, family share) over the included hexes. Average distance is visitor-share-weighted; p50_distance_km is the smallest distance at which cumulative share (sorted by distance) reaches 50%.

Site suitability (MCDA)

Criteria

For each hex h in the city, with the selected category:

Criterion Raw value x_c(h)
population population / area_km2
income median income
daytime daytime_pop / area_km2
traffic traffic index
growth growth rate
rent rent index
competition Σ_(j ∈ category, d ≤ 4 km) exp(−d_hj / 1.5)
complementary Σ_(p ∈ complement categories, d ≤ 2.5 km) exp(−d_hp / 0.8)
access (used by gap) Σ_j A_j / max(d_hj, 0.4)^λ over all stores of the category
demand (used by gap) D_h

Normalization

Min–max normalization over all hexes of the city:

x'_c(h) = (x_c(h) − min_c) / (max_c − min_c)

Kernel sums (competition, complementary, access) are log-scaled first, x ← ln(1 + x), so a single dense cluster does not compress every other hex toward zero. If max_c = min_c, the criterion is 0 for all hexes.

Direction

Cost criteria are inverted:

competition' = 1 − x'_competition
rent'        = 1 − x'_rent

Demand gap

gap(h) = x'_demand(h) · (1 − x'_access(h))

High where demand is high and existing stores’ reach is low.

Score

score(h) = 100 · Σ_c w_c · x'_c(h) / Σ_c w_c
  • w_c — user weight for criterion c, 0–10 (missing = 0; at least one must be positive).
  • Only weight ratios matter.

Top sites with spacing

Hexes are visited in descending score order; a hex is accepted if its centroid is at least min_spacing_km from all previously accepted sites, until top_n sites are selected (greedy maximal spacing).

Catchment aggregation

A ring of radius r is a geodesic buffer around the point (48 segments per quarter circle). Drive-time rings use r = minutes · v / 60, where v is the city’s average speed (Austin 42, Houston 45, Phoenix 50, Miami 35, Dubai 55 km/h). This is a radius approximation, not a network isochrone.

For each hex h intersecting ring R:

f_h = min(1, |h ∩ R| / |h|)
count_R  = Σ_h count_h · f_h                                  population, households, daytime_pop
mean_R   = Σ_h value_h · population_h · f_h / Σ_h population_h · f_h
                                                              median_income, median_age, pct_college,
                                                              pct_family, growth_rate
index_R  = (1/n) · Σ_h index_h                                traffic_index, rent_index (unweighted)

Medians and rates are therefore population-weighted means of hex values, not recomputed medians. Segment populations are Σ_h population_h · f_h per segment, and area_km2 = π · r².

Cross-shopping

For every place p in the city (all categories, each modeled against its own category):

s_p(h)          = F_hp / Σ_h' F_h'p
overlap(A, B)   = Σ_h min(s_A(h), s_B(h))
affinity(A, B)  = overlap(A, B) · m,   m = 1.35 complement, 0.6 same category, 1.0 otherwise

Results are ranked by affinity. See Cross-shopping.

Place metrics

visitors_range  = Σ_days visitors_day / (1 + 0.15 · ln(days))
frequency       = visits_range / visitors_range
avg_dwell       = Σ dwell_day · visits_day / Σ visits_day
change_pct      = 100 · (visits − visits_prev) / visits_prev
percentile      = 100 · #{same-category places in city with fewer visits} / (n − 1)

The previous period has the same length and ends the day before from.

Category parameters

Category Slug λ Trade radius (km) Base size (sq ft) Typical dwell (min) Complements
Coffee & Cafés coffee 2.2 6 1,800 18 fitness, apparel, mall, pharmacy
Grocery grocery 1.8 9 40,000 28 pharmacy, fuel, coffee, qsr
Quick Service qsr 2.0 7 3,000 14 fuel, cinema, mall, electronics
Full-Service Dining dining 1.9 10 5,000 62 cinema, hotel, mall, apparel
Fitness fitness 2.4 6 18,000 65 coffee, grocery, qsr
Apparel apparel 1.7 14 9,000 26 mall, department, coffee, dining
Pharmacy & Health pharmacy 2.1 7 12,000 12 grocery, coffee, fuel
Home Improvement home 1.5 18 100,000 34 fuel, electronics, qsr
Electronics electronics 1.6 16 25,000 30 mall, home, qsr
Department Stores department 1.4 20 120,000 45 apparel, mall, dining
Entertainment cinema 1.5 16 40,000 140 dining, qsr, mall
Hotels hotel 1.2 40 80,000 600 dining, coffee, cinema
Fuel & Convenience fuel 2.6 5 3,500 7 qsr, grocery, coffee
Shopping Centers mall 1.3 25 900,000 95 apparel, department, dining, cinema

Higher λ means steeper distance decay — customers are less willing to travel. Convenience categories combine high λ with small radii; destination categories the opposite.

Known limitations

  • Straight-line distance; no road network, travel time or barriers.
  • Competition is within-category only.
  • A single calibration factor per city and category.
  • Static demographics; no forecast of population change beyond the growth criterion.
  • All inputs in the hosted demo are synthetic (Demo data).