13. Spatial Join¶
Goal: Run a Spatial Join in ArcGIS Pro — the operation that combines two layers based on where they are.
→ For concepts, see Spatial Joins (roadmap).
Tool location¶
Geoprocessing → Spatial Join (Analysis Tools).
Parameters¶
| Parameter | Notes |
|---|---|
| Target Features | The layer that gets the joined attributes |
| Join Features | The layer providing the data |
| Output Feature Class | Where to save |
| Join Operation | JOIN_ONE_TO_ONE or JOIN_ONE_TO_MANY |
| Keep All Target Features | Yes (left join) / No (inner join) |
| Field Map | Choose which fields, and how to aggregate |
| Match Option | INTERSECT, WITHIN, CONTAINS, CLOSEST, … |
| Search Radius | Optional — for "within distance" matches |
The match option¶
| Option | Meaning |
|---|---|
| INTERSECT | Any geometric overlap |
| WITHIN | Target fully inside join feature |
| CONTAINS | Target fully contains join feature |
| CLOSEST | Picks nearest join feature; can record distance |
| WITHIN_A_DISTANCE | Match if within search radius |
| HAVE_THEIR_CENTER_IN | Polygon centroid in target |
| CLOSEST_GEODESIC | Closest, computed on the ellipsoid |
One-to-one vs one-to-many¶
flowchart LR
Tgt[Precincts<br/>22 features] --> Op{Match}
Joi[Crimes<br/>1,200 features] --> Op
Op --> One[One-to-one:<br/>22 output rows<br/>each summarized]
Op --> Many[One-to-many:<br/>1,200 output rows<br/>one per match]
classDef tgt fill:#dbeafe,stroke:#1e40af,color:#1e3a8a
classDef joi fill:#fef3c7,stroke:#f59e0b,color:#92400e
classDef out fill:#dcfce7,stroke:#10b981,color:#065f46
class Tgt tgt
class Joi joi
class One,Many out - JOIN_ONE_TO_ONE (default) → one row per target. Multiple matches get summarized by the field map.
- JOIN_ONE_TO_MANY → one row per match. Target geometry is duplicated.
Field map (the secret weapon)¶
In the Fields parameter, click each field and pick a merge rule:
| Rule | Use for |
|---|---|
Count | Total matches |
Sum | Add values |
Mean / Median | Average |
Min / Max | Extreme values |
First / Last | Just pick one |
Join | Concatenate text (e.g., comma-separated) |
Classic patterns¶
Count points per polygon¶
"Crimes per precinct"
- Target: precincts
- Join: crimes
- Match: INTERSECT
- Operation: ONE_TO_ONE
- Field map:
Join_Countfield is added automatically
Closest facility¶
"Closest fire station to each school"
- Target: schools
- Join: fire stations
- Match: CLOSEST
- Operation: ONE_TO_ONE
- Tick Distance Field Name to record the distance
Tag points with the polygon they're in¶
"Add neighborhood name to each crime"
- Target: crimes
- Join: neighborhoods
- Match: INTERSECT (or WITHIN)
- Operation: ONE_TO_ONE
- Field map: just keep
NEIGHBORHOODfrom join layer
Summarize Within (alternative)¶
For points-in-polygon counts/stats, Summarize Within is often easier than Spatial Join. Output is cleaner — a single attribute table with counts and stats.
| Tool | When |
|---|---|
| Spatial Join | You need every joined field, custom field maps, ONE_TO_MANY |
| Summarize Within | Just counts/stats, points-in-polygons |
Pitfalls¶
Watch the search radius
With WITHIN_A_DISTANCE + a small radius, you can miss matches if the layers are in a geographic CRS. Project to a projected CRS first.
Geometry won't match
Two layers showing the "same" boundaries but loaded from different sources may not perfectly overlap. Use a small search radius to absorb tiny gaps.
Practice¶
Crime per precinct
- Project precincts (polygons) and crimes (points) to State Plane.
- Spatial Join: target = precincts, join = crimes, match = INTERSECT.
- In Field Map: keep
INCIDENT_TYPEwith merge rule Count. - Symbolize precincts by the
Join_Count.
→ Next: Network Analysis.