A site-selection director ranks 12 candidate Tampa locations on drive-time demographics and competitor density. Nine steps, about three minutes of wall clock.
Site selection is an exercise in narrowing a long list. You start with 50 candidates, narrow to 12 finalists, narrow to 3 for in-person tours, sign one lease. The bottleneck is rarely "do we know what good looks like?" — it's "can we apply our criteria across 12 candidates fast enough to keep the deal warm?"
The traditional answer involved Placer.ai or SafeGraph licenses ($30K+/yr), an analyst who knew ArcGIS, and a 3-day turnaround. This walkthrough shows the modern version: nine chained operations, no GIS team, and a scored mappable shortlist at the end.
A CPG-adjacent retail concept (premium coffee, neighborhood gym, fast-casual — pick your favorite) wants to expand into Tampa. Internal criteria:
The director has a CSV of 12 candidate site addresses and a CSV of competitor locations. Their agent has Maps MCP wired in. Here's the chat.
{
"name": "bulk_match_addresses",
"arguments": {
"records": [
{ "id": "site-01", "street": "...", "city": "Tampa", "state": "FL" },
{ "id": "site-02", "street": "...", "city": "Tampa", "state": "FL" }
// ... 10 more
]
}
}
One call, 12 lat/lng pairs. Cost: free (U.S. Census geocoder).
For each site, we want a 10-minute drive polygon — the actual reachable footprint, not a Euclidean circle.
{
"name": "geo_isochrone",
"arguments": {
"centers": [/* 12 lat/lng from step 1 */],
"mode": "drive",
"minutes": 10
}
}
12 polygons. These are what the rest of the analysis joins against.
Parse the competitor CSV in your client, then ingest the records into a workspace dataset and intersect each trade-area polygon against it:
{
"name": "ingest_dataset",
"arguments": {
"slug": "competitors_tampa",
"name": "Competitor locations — Tampa MSA",
"collection": "us-zcta",
"version": "tiger-2024",
"records": [
{ "external_id": "33602", "data": { "brand": "X", "lat": 27.95, "lng": -82.46 } }
// ... one record per competitor, joined to the containing ZCTA
]
}
}
# Then for each of the 12 trade-area polygons:
{
"name": "geo_intersect_dataset",
"arguments": {
"dataset": "competitors_tampa",
"geometry": { "type": "Polygon", "coordinates": [/* one of the 12 isochrones */] }
}
}
For each of the 12 trade areas, we now know how many competitors are inside it. Filter rule: drop any site with a competitor < 1 mile (which translates to ">0 competitors in the 10-min drive polygon — close enough at this scope").
Pull median household income (B19013), population (B01003), and median age (B01002) for the ZCTAs inside each trade area:
{
"name": "query_shapes_by_intersection",
"arguments": { "polygons": "trade_areas_step_2", "collection": "us-zcta" }
}
{
"name": "census_acs",
"arguments": {
"geo": "us-zcta",
"tables": ["B19013", "B01003", "B01002"],
"ids": "zcta_ids_step_4a"
}
}
For each trade area, the agent computes a population-weighted average of median income and density. (This is the kind of arithmetic any LLM does cleanly given the input rows — no notebook needed.)
The agent scores each of the 12 sites against the four criteria, ranks them, and renders a map:
{
"name": "create_report",
"arguments": {
"slug": "tampa-12-sites",
"name": "Tampa site selection — 12 candidates scored",
"is_public": false,
"config": {
"layer": {
"polygons": "trade_areas_step_2",
"points": "candidates_geocoded",
"color_by": "score",
"tooltip": ["score", "median_hhi", "density", "competitors"]
}
}
}
}
Internal-only report (public: false). The report has a private URL that only the workspace can see. Pro tier can lock embed iframes to a specific domain via config.embed_origins.
{
"name": "describe_report",
"arguments": { "report": "tampa-12-sites" }
}
The response is a prose summary keyed off the rendered values: which sites pass all criteria, which fail each one, where the income-vs-competition trade-offs sit. Useful as a starting point for the deck — re-runnable when criteria change. The output is grounded in the actual report data, so the numbers cited line up with what the iframe shows.
Is: a fast first pass that turns 12 candidates into 3 finalists using uniform criteria. Same job a junior analyst used to spend 2 days on, now ~3 minutes of wall clock.
Isn't: a substitute for the in-person tour, the parking-lot count, or the broker conversation. It's the screening pass before those things, not a replacement.
/v/tampa-12-sites.png?width=1600&height=1000&dpi=2 gives you a retina-grade image ready for Keynote.