Two grids that share no index cannot be joined by a lookup — apportioning a measured quantity (population, audience, spend) from one to the other is a geometry problem, and the honest output is a per-link weight table, not a single mapping. This is the measurement counterpart to the trafficking rule:
Inside an overlay (a set operation you traffic on), mixing cell systems is rejected outright — see cross-system guardrails: within one grid, normalize-then-subtract is exact algebra. For measurement, you reconcile across grids through this declared weighted crosswalk. Same fact, two regimes: exact algebra when you traffic, declared geometry when you measure.
Per-link weights
cross_system_crosswalk tiles a source cell with the target-system cells that
overlap it and returns one link per overlap, each carrying the fraction of the
source apportioned to that target:
- weight
- The apportionment factor for this target — how much of the source's quantity it receives.
- sourceCoverageFraction
- intersection ÷ source area — the source's own view of the split.
- targetCoverageFraction
- intersection ÷ target area — how much of the target the source fills.
- by_geo
- The target cell's system discriminator, so the weights are never mistaken for the source grid.
Area-weighted is the default, and its weights sum to the covered fraction (≈1 when the target set contains the source). It is the correct choice when the quantity being moved is uniform over area. It is the wrong choice when it is not — population is not spread evenly inside a cell — which is what the weight surface is for.
The weight method is chosen by what the row measures
- area_weighted (default)
- Split by intersection area. Right for area-uniform quantities; biased for anything concentrated (population, footfall).
- declared mass surface
- Re-derive the weights from a supplier's mass (population, auxiliary). The right method when the row measures people, not land.
- centroid (budget)
- Assign the whole source to the single target holding its centroid. Deterministic and cheap; the tool reports the misassigned fraction as centroid_error.
- common-refinement (budget)
- Refine both grids to a shared finer grid and sum. Deterministic, higher cost, lower error than centroid — the accuracy/cost dial.
The method is not a preference; it is dictated by the quantity. Area-weighting a population count silently assumes people are spread like paint, which they are not — the visible error the round trip already quantifies (measured H3 ↔ S2 round trip) is an area error, and a mass error can be larger.
Declaring a weight surface
A mass surface is a commercial extension point, not a free primitive: the rails
compute the consequence of a declaration, they do not supply the mass. Passing a
weightSurface records the declaration as link provenance — the same
registry-row shape as a crosswalk's regionProvenance:
- supplier
- Who supplies the mass surface (e.g. an ACS/LODES-derived population product).
- version / vintage
- The edition and the period the mass is valid for — weights are only as current as the surface.
- unit
- What the mass counts (e.g. residential_population), so a consumer knows what the weight apportions.
- applied
- false until the supplier's mass is actually joined — the tool echoes the declaration and keeps area weights as the fallback, never inventing the mass.
The declaration travels with the weights so a downstream reader can always tell an area-weighted split from a population-weighted one, and can trace the mass back to the row that produced it. A weight without its surface is an assumption; a weight with its declared surface is an auditable measurement.
