mcpField
C
carto-territory-planning

carto-territory-planning

github.com/cartodbData & databases655 installsUpdated 1w ago
Repository

About carto-territory-planning

A skill for CARTO Workflow builders addressing territory balancing and facility location allocation. It guides the process from loading and indexing spatial data through optimization and saving results, for balancing demand across contiguous areas or selecting locations to improve coverage or reduce distance costs.

Key features

  1. 01Build balanced, contiguous territories
  2. 02Assign territories by demand and similarity
  3. 03Select facilities to maximize demand coverage
  4. 04Select facilities to minimize weighted distance
  5. 05Save and validate planning workflows

Use cases

  1. 01Divide sales regions by revenue or workload
  2. 02Design service zones balanced by population
  3. 03Plan warehouse or emergency response locations
  4. 04Combine facility selection with territory assignment

MCP support

Used alongside the carto-create-workflow skill. When the MCP server is attached, workflow construction, validation, and execution use the create_workflow, validate_workflow, and run_workflow tools.

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/cartodb/agent-skills --skill carto-territory-planning

After installing, type/carto-territory-planningin Claude Code to confirm it loaded.

Details

From the project README

Territory Planning (Territory Balancing + Location Allocation)

Builds CARTO Workflows that solve two related spatial optimization problems: dividing areas into balanced territories (e.g. sales regions, service zones) and finding optimal facility locations that maximize coverage or minimize cost.

Prerequisites: Load carto-create-workflow for the development process, JSON structure, and validation. It covers both access paths — the MCP server's workflow tools (create_workflow, validate_workflow, run_workflow) when attached, the carto workflows CLI otherwise. Routing signals: carto-basics/references/access-paths.md. Both components require the Territory Planning Extension Package installed on the connection.


Territory Balancing

Divides a study area into spatially contiguous territories that are balanced by a demand variable (e.g. workload, population, revenue).

Pipeline
Source Data (points) -> Spatial Indexing -> Aggregate per Cell -> Territory Balancing -> Save
Step 1: Load Source Data

Use native.gettablebyname. Input is typically point data with one or more numeric metrics to balance.

Success: Node outputs a table with a geometry column and numeric metric columns.

Step 2: Convert to Spatial Index

Use native.h3frompoint (or native.quadbinfromgeopoint) to assign each point to a grid cell.

Resolution guidance: Higher resolution = smaller cells = finer-grained territories, but more computation. H3 resolution 8-9 is typical for city-level analysis.

Success: Output has a spatial index column (e.g. h3).

Step 3: Aggregate per Cell

Use native.groupby to produce one row per cell with the metrics to balance:

  • Group by: the spatial index column (h3)
  • Aggregation: e.g. geom,count,revenue,sum,population,avg

Success: One row per cell with numeric columns for demand and optional similarity features.

Step 4: Run Territory Balancing

Use native.territorybalancing with:

InputDescriptionExample
input_tableTable input (from previous step)
index_columnH3 or Quadbin columnh3
demand_columnNumeric column to balance across territoriesgeom_count
similarity_featsOptional numeric columns for within-territory similarity["sentiment_avg", "popularity_avg"]
npartitionsNumber of territories to create9
keep_input_columnsInclude all input columns in outputtrue

Success: Output contains all input rows with an additional territory assignment column. Each cell is assigned to exactly one territory.

Step 5: Save

Use native.saveastable to persist results. The spatial index column is directly visualizable in CARTO Builder, colored by territory ID.

Success: Validated workflow uploadable via create_workflow (MCP) or carto workflows create (CLI).


Location Allocation

Finds the optimal subset of candidate facility locations that either maximize demand coverage or minimize total cost/distance.

Pipeline
Demand Data (grid/points) -> Candidate Locations -> Location Allocation -> Save
Step 1: Load Demand Data

Use native.gettablebyname to load a grid or point dataset representing demand (e.g. population per H3 cell, customer locations).

Success: Table with a spatial index column and a numeric demand column.

Step 2: Load Candidate Locations

Use a second native.gettablebyname for potential facility locations (e.g. existing infrastructure, candidate sites).

If candidates need filtering, use native.wheresimplified or native.limit to reduce the set -- fewer candidates = faster computation.

Success: Table with a spatial index column representing candidate sites.

Step 3: Run Location Allocation

Choose the variant based on the objective:

Maximize Coverage

Use native.locallocallocation_maximizecoverage:

InputDescriptionExample
demandTable with demand values
demand_index_columnSpatial index column in demand tableh3
demand_columnNumeric demand variablepopulation
candidatesTable with candidate locations
candidates_index_columnSpatial index column in candidates tableh3
nfacilitiesNumber of facilities to open5
coverageradiusMaximum service distance (meters for geography)5000

Success: Output identifies which facilities to open and which demand cells each facility serves, maximizing total covered demand within the radius.

Minimize Total Cost

Use native.locallocallocation_minimizetotalcost. Same inputs as Maximize Coverage but without coverageradius — the objective is total weighted travel distance, not coverage within a radius.

Success: Output identifies which facilities to open, minimizing total weighted travel distance between demand and assigned facilities.

Step 4: Save

Use native.saveastable to persist results.

Success: Validated workflow uploadable via create_workflow (MCP) or carto workflows create (CLI).


Gotchas

  • Provider casing & SQL dialect. This skill uses lowercase column names (h3, geom_count, population, sentiment_avg, etc.) — BigQuery / Databricks / Postgres / Redshift convention. On Snowflake, unquoted identifiers surface UPPERCASE — reference them as H3, GEOM_COUNT, POPULATION, SENTIMENT_AVG. See carto-create-workflow/references/providers/<provider>.md for casing rules and SQL dialect equivalents.
  • Extension package required: Both territory balancing and location allocation require the Territory Planning Extension Package installed on the specific connection being used. This is NOT available by default -- the user must have it installed. Validation will fail if the package is missing.
  • Location allocation is computationally expensive with many candidates. Pre-filter candidates (by geography, capacity, or other criteria) to keep the candidate set small. Hundreds of candidates can be slow; thousands may time out.
  • Coverage radius units depend on the spatial reference system -- typically meters when using geography types. Verify the unit matches your intent.
  • Territory balancing optimizes a trade-off between spatial contiguity and balance. Perfect balance is not guaranteed -- territories will be approximately equal in the demand variable, not exactly equal.
  • Grid resolution sensitivity: Results change significantly with the input grid resolution. Finer grids give more precise boundaries but increase computation. Start with H3 resolution 8 for city-scale and adjust.
  • The component names use native.territorybalancing (no dot separator in "territory balancing") and native.locallocallocation_maximizecoverage / native.locallocallocation_minimizetotalcost (note the double "local" prefix).
  • Demand data must cover the study area. Gaps in the demand grid mean those areas are invisible to the optimizer. Use polyfill + COALESCE(value, 0) if you need full coverage.

Reference Templates

Academy Tutorials

Common Variations

VariantHow
Sales territory balancingPoints -> H3 -> aggregate revenue per cell -> territory balancing with revenue as demand
Service zone designGrid with population -> territory balancing to create equal-population zones
Warehouse/depot placementPopulation grid as demand + existing warehouses as candidates -> minimize total cost
Emergency response hubsPopulation grid as demand + candidate sites -> maximize coverage with a response-time radius
Retail network expansionCustomer density grid as demand + potential store locations -> maximize coverage
Combined territory + allocationFirst run location allocation to pick hub locations, then run territory balancing to assign areas to each hub

Comments

Markdown supported