Skip to content

fix(#364): coarse-overlay example weights by land_area_km2, not the removed nland - #365

Merged
cboettig merged 1 commit into
mainfrom
fix/364-coarse-overlay-land-area
Aug 9, 2026
Merged

fix(#364): coarse-overlay example weights by land_area_km2, not the removed nland#365
cboettig merged 1 commit into
mainfrom
fix/364-coarse-overlay-land-area

Conversation

@cboettig

@cboettig cboettig commented Aug 8, 2026

Copy link
Copy Markdown
Member

Fixes #364.

h3-guide.md's coarse-resolution overlay example read nland from the …-hex-weights-res8 / -res9
assets. data-workflows#524 removed that column (2026-08-07, an hour after #357), so the example was a
hard SQL error on any res-8/res-9 question:

SQL Error: Binder Error: Table "p" does not have a column named "nland"

Source fix, not a method change: the weight now comes from the region's land-grid rollup
(ca30x30-ecoregion, assets ecoregion-hex-res9 / -res8), which publishes an exact per-cell
land_area_km2 — the summed area of the actual res-10 land children rather than a count times the
parent's area. That is also verbatim the form the -hex-weights-res9 / -res8 asset descriptions
document, so the injected guide and the per-dataset text stay on the same form (the point of #357).

Verified against prod

Statewide GAP 1+2 at res 8, with the new block:

SELECT 100 * SUM(COALESCE(p.w1 + p.w2, 0) * e.land_area_km2) / SUM(e.land_area_km2)
FROM read_parquet('s3://public-ca30x30/ecoregion/hex-res8/h0=*/data_0.parquet') e
LEFT JOIN read_parquet('s3://public-ca30x30/conserved-areas-terrestrial-2025/hex-weights-res8/h0=*/data_0.parquet') p USING (h8, h0);
-- 26.1348

matching the res-10 ground truth (26.135%) and the nland × h3_cell_area product the guide used to
name. Also ran the filtered three-table shape as written (Mojave Desert as a res-8 feature): 44.87%
at res 8 against 44.70% at res 10 — the residual is the coarse feature's own footprint spill, which
is inherent to asking at res 8, not a weighting error.

The two res-8 assets are 1:1 over the same footprint (525,034 rows each, zero land cells without a
weights row), so the LEFT JOIN + COALESCE is defensive here and load-bearing at res 10.

One deviation from the issue's suggested diff

#364 proposes a three-line block with a bare WHERE <feature filter> and no feature table. That
would not bind — the section's premise is a coarse feature overlaid on a finer layer, so the
feature has to be in the query. I kept the feat CTE from the current block and joined the land grid
to it:

WITH feat AS (
  SELECT DISTINCT h8, h0
  FROM read_parquet('<res-8 feature hex>')
  WHERE <feature filter>
)
SELECT 100 * SUM(COALESCE(p.w1 + p.w2, 0) * e.land_area_km2)
           / SUM(e.land_area_km2) AS pct_conserved
FROM feat f
JOIN read_parquet('<ecoregion hex-res8>') e USING (h8, h0)
LEFT JOIN read_parquet('<conserved-areas hex-weights-res8>') p USING (h8, h0);

Everything else follows the issue: line 318's rule names land_area_km2 and the land-grid assets,
line 331 becomes "the land grid is both the weight and the denominator", and the res-9 / frac
variants at line 336 drop to prose. Net: one fewer inline formula, same number of SQL blocks.

Relation to #362

#362 (prod v0.8.12 → v0.8.13) would ship the broken section, so it should take this commit and
re-gate. Its green gate exercised the res-10 path (CWHR13 percent-conserved), which is unaffected —
it never touched the broken branch. A gate cell asking a res-8 or res-9 feature question would.

…and grid

The res-8/res-9 weights assets no longer carry nland (data-workflows#524),
so the coarse-resolution overlay example was a binder error, not a wrong
number. Take the weight from the region's land-grid rollup
(ca30x30-ecoregion, ecoregion-hex-res9/-res8), which publishes an exact
per-cell land_area_km2 — same 26.135% statewide as the res-10 ground
truth, and the form the -hex-weights-res9/-res8 asset descriptions
already document.

The land grid is joined for the weight, so it is also the denominator and
the land bound; the h3_cell_area() call goes away. Res-9 and the
hex-fractions variant drop to prose.
@cboettig

cboettig commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

Verified against live data before merge — this is the check that would have caught #364, and it is not something the regression tier can currently do (geo-agent-benchmark#21).

Running this PR's recipe statewide, against the res-10 ground truth for the same scope:

-- this PR's recipe at res 8
WITH feat AS (SELECT DISTINCT h8, h0 FROM read_parquet('s3://public-ca30x30/ecoregion/hex-res8/h0=*/data_0.parquet'))
SELECT 100 * SUM(COALESCE(p.w1 + p.w2, 0) * e.land_area_km2) / SUM(e.land_area_km2)
FROM feat f
JOIN read_parquet('s3://public-ca30x30/ecoregion/hex-res8/h0=*/data_0.parquet') e USING (h8, h0)
LEFT JOIN read_parquet('s3://public-ca30x30/conserved-areas-terrestrial-2025/hex-weights-res8/h0=*/data_0.parquet') p USING (h8, h0);
-- 26.135
this PR, res 8 26.135
res-10 ground truth 26.135
pre-#522 nland count-weighting 25.684
the code on main today binder error

Exact to three decimals. It also drops the h3_cell_area() call the old form required, so the corrected block is shorter than the one it replaces.

Ready to merge from my side. Next: tag v0.8.14 and promote by digest — #362 (promote v0.8.13) is closed as superseded, since v0.8.13 carries the #364 break.

Coordination note: further edits to this block are sequenced under #367, behind the gate-coverage work, so this should be the last patch here before that design pass.

@cboettig
cboettig merged commit 0f2fc25 into main Aug 9, 2026
1 check passed
@cboettig
cboettig deleted the fix/364-coarse-overlay-land-area branch August 9, 2026 20:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

h3-guide: the coarse-resolution overlay example reads nland from the weights asset, which no longer has it — binder error

1 participant