Huff visit forecast
Forecast daily and annual visits for a candidate location with a calibrated Huff gravity model, and read its market share and trade area.
The Huff forecast estimates how many visits a new store would get at a specific location, given the stores of the same category that already exist in the city. It is the tool to use once you have a candidate address and need a number for the business case.
The idea in one paragraph
Every hex cell in the city has a pool of shopping demand. Shoppers in a hex split that demand across nearby stores in proportion to each store’s attractiveness and inversely to distance, raised to a category-specific power λ. Some share always goes to an “outside option” — shopping elsewhere or not at all. Add a candidate store, and every hex re-splits its demand: the candidate captures some, and existing stores lose some. The model’s raw “expected demand” units are then calibrated against the observed visits of existing stores so the forecast comes out in visits per day.
Inputs
| Input | Description | Default |
|---|---|---|
city, category |
Market and store category | required |
lng, lat |
Candidate location; must be inside the city’s study area | required |
sqft |
Planned floor area, 100–2,000,000 | category’s typical size |
brand_strength |
Operator strength multiplier, 0.6–1.5 | 1.0 |
Attractiveness
A = (sqft / base_sqft)^0.7 · brand_strength
base_sqft— the category’s typical size (coffee 1,800; grocery 40,000; shopping center 900,000).- The exponent 0.7 gives diminishing returns: doubling floor area raises attractiveness by about 62%, not 100%.
brand_strength— 1.0 is an average operator. In the demo dataset fictional chains range from 0.9 to 1.2; independents from 0.8 to 1.15.
Outputs
| Field | Meaning |
|---|---|
attractiveness |
The candidate’s A |
calibration_k |
Visits per unit of modeled demand, fitted on existing stores |
predicted_daily_visits |
k · E_candidate |
predicted_annual_visits |
Daily × 365 |
market_share |
Candidate’s share of all modeled category demand captured by stores after it opens |
category_avg_daily_visits |
Average observed daily visits of existing stores in the category (last 90 days) |
total_cannibalized_daily |
Total daily visits existing stores are expected to lose |
impacted |
Up to 10 most-affected existing stores (Cannibalization) |
trade_area |
GeoJSON hexes covering the first 80% of the candidate’s modeled visitors, with share |
A useful first read is predicted_daily_visits ÷ category_avg_daily_visits. Above 1.0 means the candidate would out-perform the typical store in the category; well below 1.0 usually means a saturated area or a weak format assumption.
Calibration
The gravity model produces expected demand E_j for each store — a relative quantity in “population units”. To turn it into visits, MapDove fits a single scaling factor for the city and category:
k = Σ_j observed_avg_daily_visits_j / Σ_j E_j
summed over all existing stores of the category, using observed visits from the last 90 days of data. The candidate’s forecast is k · E_candidate. This means the forecast inherits the overall visit level of the category in that city, and the gravity model only decides how that level is distributed in space.
How to use it well
- Model the format you will actually open. Size and brand strength move the forecast more than small location shifts.
- Test a few pins. Moving the candidate 300–500 m (across a highway, into a center) can change both the forecast and the cannibalization.
- Pair it with suitability. Suitability says where conditions are favorable; Huff says how much traffic a store would capture there given today’s competitors.
- Compare against your own stores. If your brand’s existing stores are among
impacted, the net gain ispredicted_daily_visits − (your stores' losses).
Limitations
- One category at a time. The competitive set is stores of the same category only.
- Straight-line distance between hex centroids and stores, with a 0.4 km floor so a hex containing a store does not get infinite utility.
- Static demand. Population and daytime population do not change when the store opens; the model redistributes demand, it does not create new demand beyond what the outside option releases.
- Single calibration factor per city and category; it does not capture store-level quality differences beyond attractiveness.
- Demo data. Observed visits used for calibration are synthetic (Demo data).
The formulas, including the outside option, are written out in Methodology. The API is documented in SDSS endpoints.