SEEA EA 2024 · Annex worked example · Phase 1 replication target

SEEALand, end to end

The standard's own toy landscape: 250 hectares, six ecosystem types, one accounting year, and a single 2-hectare forest→cropland conversion that propagates through all five accounts. Reproducing these exact numbers is the cheapest possible proof that our engine implements the standard and not an approximation of it.

Every number on this page is synthetic. SEEALand is a stylised example invented by the standard's authors — there is no study site, no satellite imagery, no survey. The hectare grid, the condition variables, the service flows and the prices are all assumed values chosen to make the arithmetic legible.

What is real is the vocabulary and the algebra: the IUCN GET ecosystem types, the Ecosystem Condition Typology, the ES reference list, the supply-and-use structure, and the NPV decomposition. That is precisely what makes it a good fixture — it pins down our account arithmetic with no data dependency at all. Where the diagram below names a real catalog layer, it is marked unseea and describes what we will substitute later, not something SEEALand uses.

Accounting area
250 ha
Ecosystem types
6
Period
2020
The one change
2 ha
GEP
$83,125
Asset value Δ
+$51,244

The landscape, and the one thing that happens to it

Each square is 1 ha, drawn from the standard's own spreadsheet (figures AI.1–AI.2, p. 371). The whole extent account traces back to these two grids, and the entire difference between them is two cells at the bottom-left of the forest block.

Opening extent1 Jan 2020
Closing extent31 Dec 2020

The conversion (outlined in rust): 2 ha of forest becomes cropland. In the accounts this is one managed reduction and one managed expansion — but for forest it moves extent, condition, service flows, GEP and asset value through four different mechanisms. That propagation is what the replication actually tests.

Six storylines, not one

A common misreading — and one an earlier draft of this page invited — is that the 2-hectare conversion drives every number in the accounts. It does not. The annex (p. 370) sets out a changing ecological context in which several independent pressures act at once. The conversion drives the forest story; seagrass's $163,946 of degradation has nothing to do with it.

Forest

Converted at the margin, and the remaining block suffers edge effects that impair its ecological functioning. This is the one storyline the conversion causes.

condition −0.0590
Lake

Long-term efforts to improve water quality pay off. The only ecosystem type that improves, and the only one posting ecosystem enhancement.

condition +0.0456
Cropland

Gains 2 ha from the conversion. Policies to improve cropland condition have mixed outcomes, so its condition is nearly flat.

condition +0.0034
Urban area

Urban intensification drives a loss of green space within an unchanged footprint — extent is static while condition falls.

condition −0.0192
Wetland

Caught by the same general intensification of ecosystem use as forest, without any change in its own extent.

condition −0.0353
Seagrass

Sewerage overflow from the urban area. The worst condition decline in SEEALand, and entirely unrelated to the land conversion.

condition −0.0759

Prices move too, and for stated reasons. Wood and wild fish prices rise on higher demand plus tighter sustainability regulation constraining supply; the price of global climate regulation rises to reflect increasing marginal damages from carbon release. These price changes are what produce the revaluation entries in the asset account — and, as the closing section shows, they are large enough to flip the sign of the headline number.

The five accounts, in dependency order

The numbering is real: each account consumes the one above it. Extent defines the rows every later table is indexed by; condition and service flows are measured per ecosystem type; monetary values price the flows; the asset account discounts them forward and reconciles the opening and closing balance sheet.

1

Ecosystem extent account

SEEA EA Ch. 4 · Annex I tables AI.2–AI.3, p. 372

What the step does

Partitions the accounting area into mutually exclusive, exhaustive ecosystem types and measures each one's area at the opening and closing dates.

Change is not just a delta — it is split into managed vs. unmanaged expansion and reduction, and cross-tabulated as a from→to change matrix whose diagonal is unchanged area.

Inputs

SEEALand — assumed
  • A hand-drawn 1-ha cell map at two dates, typed to IUCN GET Level 3 (EFG)
unseea — real layers
  • cgls-lc100-2019/hex-fractions res-9 areal fraction per class in catalog
  • overturemaps/countries/hex res-8, as the accounting area in catalog
  • A second date for real change accounting — annual NLCD, then ESA CCI LC pending

What comes out

  • Area per ET: opening / additions / reductions / closing
  • The ET change matrix — the only place conversions are recorded
  • The row index every downstream account uses
SEEALand values to reproduce Forest 40 → 38 ha Cropland 60 → 62 ha Lake / Urban / Wetland / Seagrass unchanged Total 250 ha, net change 0
SQL — the real-data equivalent4.3 s · validated
WITH aoi AS (                       -- the ecosystem accounting area, as res-8 hexes
  SELECT DISTINCT h8
  FROM read_parquet('s3://public-overturemaps/2026-02-18.0/countries/hex/h0=*/data_0.parquet')
  WHERE h0 IN (578290339652042751, 578395892768309247)
    AND country = 'CR' AND class = 'land'
)
SELECT f.lc_class,
       ROUND(SUM(f.frac * h3_cell_area(f.h9, 'km^2')), 1) AS area_km2
FROM read_parquet('s3://public-land-cover/cgls-lc100-2019/hex-fractions/h0=*/data_0.parquet') f
SEMI JOIN aoi a ON f.h8 = a.h8
WHERE f.h0 IN (578290339652042751, 578395892768309247)
  AND f.lc_class NOT IN (0, 200, 80, 255)   -- no-data, open sea, water, sentinel
GROUP BY f.lc_class
ORDER BY area_km2 DESC;

frac × cell area is the primitive the whole account rests on. Over Costa Rica it returns 51,078 km² against the country's own land polygon at 51,181 km² — −0.20%. Constraining h0 is partition pruning for speed; the SEMI JOIN is what actually clips to the accounting area.

2

Ecosystem condition account — three stages, not one

SEEA EA Ch. 5 · Annex I tables AI.4a–AI.5, pp. 373–375

What the step does

2a Variables. Observe raw measurements per ET, filed under the SEEA Ecosystem Condition Typology: A1 physical, A2 chemical, B1 compositional, B2 structural, B3 functional, C1 landscape.

2b Indicators. Rescale each variable to [0,1] against a lower and upper reference level. Direction can invert — for lake nitrogen the lower bound is 2 mg/l and the upper is 0.

2c Index. Weight indicators up the ECT tree into one index per ET. Forest weights: abiotic ⅓, biotic ½, landscape ⅙.

Inputs

SEEALand — assumed
  • Forest: NDWI, soil organic carbon, foliar N, tree species richness, tree cover, NDVI, forest area density
  • Reference levels stated outright — natural for forest/lake/wetland/seagrass, anthropogenic for cropland/urban
unseea — real layers
  • B1 globio-msa-2015-overall — already [0,1] vs. undisturbed, so 2b is the identity in catalog
  • C1 h3_grid_disk over hex land cover — the forest-area-density analogue in catalog
  • A2 SoilGrids SOC · A1 HydroSHEDS, Global Surface Water pending
  • Reference-level tables per ET and biome — the hardest unsolved piece pending

What comes out

  • A condition index per ET, opening and closing
  • Net change decomposed into Δabiotic / Δbiotic / Δlandscape
  • The volume effect input to stage 5 — condition change is what degradation and enhancement mean in money
SEEALand values to reproduce Forest 0.6707 → 0.6118 Δ forest −0.0590 of which landscape −0.0250 Lake +0.0456 Seagrass −0.0759 Cropland +0.0034
SQL — B1 compositional condition, by ecosystem type6.5 s · validated
WITH aoi AS (
  SELECT DISTINCT h8
  FROM read_parquet('s3://public-overturemaps/2026-02-18.0/countries/hex/h0=*/data_0.parquet')
  WHERE h0 IN (578290339652042751, 578395892768309247)
    AND country = 'CR' AND class = 'land'
),
lc AS (                             -- how much of each ET sits inside each res-8 cell
  SELECT h8, lc_class, SUM(frac * h3_cell_area(h9, 'km^2')) AS et_km2
  FROM read_parquet('s3://public-land-cover/cgls-lc100-2019/hex-fractions/h0=*/data_0.parquet')
  WHERE h0 IN (578290339652042751, 578395892768309247)
    AND lc_class NOT IN (0, 200, 80, 255)
  GROUP BY h8, lc_class
)
SELECT lc.lc_class,
       ROUND(SUM(g.msa * lc.et_km2) / SUM(lc.et_km2), 4) AS msa_by_et,
       ROUND(SUM(lc.et_km2), 1) AS et_area_km2
FROM lc
JOIN read_parquet('s3://public-globio/globio-msa-2015-overall/hex/h0=*/data_0.parquet') g
  ON g.h8 = lc.h8 AND g.h0 IN (578290339652042751, 578395892768309247)
SEMI JOIN aoi a ON lc.h8 = a.h8
GROUP BY lc.lc_class
ORDER BY et_area_km2 DESC;

MSA is a bounded intensity, so this is an area-weighted mean, never a sum. The result orders as ecology predicts — closed broadleaf forest 0.544, cropland 0.266, urban 0.241 — which is the real evidence the join is right. MSA needs no rescaling step: it already runs [0,1] against an undisturbed reference, so stage 2b is the identity for this one variable.

SQL — C1 landscape: forest area density over a k-ring3.4 s · validated
WITH aoi AS (
  SELECT DISTINCT h8
  FROM read_parquet('s3://public-overturemaps/2026-02-18.0/countries/hex/h0=*/data_0.parquet')
  WHERE h0 IN (578290339652042751, 578395892768309247)
    AND country = 'CR' AND class = 'land'
),
forest AS (                         -- neighbour universe: NOT clipped, so k-rings aren't truncated
  SELECT h9, h8, SUM(frac) AS forest_frac
  FROM read_parquet('s3://public-land-cover/cgls-lc100-2019/hex-fractions/h0=*/data_0.parquet')
  WHERE h0 IN (578290339652042751, 578395892768309247)
    AND lc_class BETWEEN 111 AND 126
  GROUP BY h9, h8
),
focal AS (                          -- but score only the cells inside the accounting area
  SELECT f.h9 FROM forest f SEMI JOIN aoi a ON f.h8 = a.h8
),
nbr AS (
  SELECT f.h9 AS focal, UNNEST(h3_grid_disk(f.h9, 3)) AS neighbour FROM focal f
)
SELECT n.focal,
       AVG(COALESCE(f2.forest_frac, 0)) AS forest_area_density
FROM nbr n LEFT JOIN forest f2 ON f2.h9 = n.neighbour
GROUP BY n.focal;

This is the variable that carries SEEALand's forest decline — 74% → 59% in the annex. On an H3 grid the metric that normally needs dedicated raster tooling is one UNNEST. Measured: 404,240 focal cells at k=3 in 3.4 s; raising k from 1 to 40 multiplies rows by 700× but wall clock by only 9×, so the neighbourhood radius is effectively free and EAA size is what binds.

3

Ecosystem services flows, in physical terms

SEEA EA Ch. 6–7 · Annex I tables AI.6–AI.7, pp. 377–378

What the step does

For each service, quantifies the flow generated in the period and records it in a supply-and-use table: supplied by ecosystem type, used by industry, government or households.

Total supply must equal total use, service by service. Services used by other ecosystems are intermediate and must not be counted in the aggregate.

Inputs

SEEALand — assumed
  • Stated physical flows for 6 services across the 6 ETs, with no model behind them
unseea — real layers
  • Per-service logic chains from the UNSD biophysical modelling guidelines pending
  • Climate regulation: carbon stock and flux layers pending
  • Extent (stage 1) and condition (stage 2) both enter as modifiers

What comes out

  • Physical supply-and-use table, balanced
  • Expected opening and closing flows per ET — the quantity series stage 5 discounts
SEEALand values to reproduce Wood 140 m³ Crop 150 t Wild fish 9 t Climate regulation 425 tCO₂ Water purification 7 t N Recreation 9,800 visits
SQL — the one service we can compute today: carbon retention3.8 s · validated
WITH aoi AS (
  SELECT DISTINCT h8
  FROM read_parquet('s3://public-overturemaps/2026-02-18.0/countries/hex/h0=*/data_0.parquet')
  WHERE h0 IN (578290339652042751, 578395892768309247)
    AND country = 'CR' AND class = 'land'
)
SELECT ROUND(SUM(c.carbon) / 1e6, 2) AS mt_irrecoverable_c
FROM read_parquet('s3://public-carbon/irrecoverable-carbon-2024/hex/h0=*/data_0.parquet') c
SEMI JOIN aoi a ON c.h8 = a.h8
WHERE c.h0 IN (578290339652042751, 578395892768309247);

SUM is correct here, and it is the exact opposite of the MSA rule above. carbon is a per-cell total (an amount), so it sums; MSA is a per-cell intensity, so it averages. The two look identical in SQL and produce silently wrong accounts if swapped. Costa Rica: 52.93 Mt C irrecoverable, 2024.

To split it by ecosystem type you apportion the amount by frac and then sum — the mirror image of weighting an intensity by area and then averaging. Both layers are native res 9, so that join is exact. The rest of the service list needs the biophysical logic chains and is not yet computable.

4

Monetary services account, and Gross Ecosystem Product

SEEA EA Ch. 8–9 · Annex I tables AI.8–AI.9, pp. 379–380

What the step does

Prices each physical flow at its exchange value — the price it would fetch in a market, deliberately not a welfare or willingness-to-pay value.

Summing final services supplied gives Gross Ecosystem Product, the headline aggregate that sits alongside GDP.

Inputs

SEEALand — assumed
  • Physical flows from stage 3
  • Prices: wood $60/m³, crop $75/t, fish $350/t, CO₂ $25/t, N $100/t, visit $5
unseea — real layers
  • Prices become a visible control panel defaulting to SEEALand's, because the carbon price is genuinely contested pending

What comes out

  • Monetary supply-and-use table
  • GEP, and its split by ecosystem type
  • The price series stage 5 needs for revaluation
SEEALand values to reproduce Forest $19,650 Lake $26,050 Cropland $11,250 Urban $12,625 Wetland $1,200 Seagrass $12,350 GEP $83,125
No SQL — and that is the pointarithmetic, not a query

Stages 4 and 5 are price × quantity and a discount factor. There is no spatial data to query: once stage 3 has produced physical flows per ecosystem type, the monetary accounts are ordinary arithmetic over a small table.

That is exactly why Phase 1 is blocked on nothing. We can implement and test the entire monetary half of the standard against SEEALand's own numbers without a single catalog layer — and the prices, discount rate and asset life become visible controls in the app rather than buried constants, because the standard itself treats them as illustrative rather than prescribed.

5

Monetary ecosystem asset account

SEEA EA Ch. 10–11 · Annex I tables AI.10–AI.11, pp. 381, 383

What the step does

Discounts each ET's expected future service flows to a net present value — 100-year asset life, 2% real discount rate, income at period end — then reconciles opening to closing value.

The reconciliation is the clever part. The NPV change is decomposed into an area, a volume and a price effect, and each maps onto a different accounting entry.

Inputs

SEEALand — assumed
  • Expected flows and prices, opening and closing (stages 3–4)
  • Asset life 100 years, discount rate 2% real — stated as illustrative, not prescribed
unseea — real layers
  • Area per ET (stage 1) drives the area effect; condition change (stage 2) drives the volume effect
  • Discount rate and asset life become user-visible controls, SEEALand's values as defaults pending

What comes out

  • NPV per ET, opening and closing
  • The full balance-sheet reconciliation: enhancement, degradation, conversions, reappraisals, revaluation
  • Area effect → conversion; volume effect → degradation / enhancement; price effect → revaluation
SEEALand values to reproduce Opening $3,572,207 Closing $3,623,451 Forest ΔNPV −$116,366 = area −$43,435 + volume −$108,111 + price +$35,180
The decomposition, as arithmeticSEEA EA appendix A10.1
NPV factorises exactly into three terms, per ecosystem type and service:

    Q = expected annual flow × asset life        a = area, hectares
    q = Q / a      quantity per hectare          p = NPV / Q, implied unit price

    NPV = a · q · p

The change is split symmetrically across the three factors — the Shapley
decomposition of a product — so the parts sum exactly to the whole, with
no residual left over to dump somewhere:

    area   = (a₁−a₀) · ( (q₀p₀ + q₁p₁)/3 + (q₀p₁ + q₁p₀)/6 )   → CONVERSION
    volume = (q₁−q₀) · ( (a₀p₀ + a₁p₁)/3 + (a₀p₁ + a₁p₀)/6 )   → DEGRADATION / ENHANCEMENT
    price  = (p₁−p₀) · ( (a₀q₀ + a₁q₁)/3 + (a₀q₁ + a₁q₀)/6 )   → REVALUATION

Forest, all three services summed:

    −43,435  +  −108,111  +  +35,180  =  −116,366

This decomposition is the load-bearing idea of the whole standard. Without it you have a single number for the change in asset value and no way to post it: a conversion, a degradation and a price rise are three different accounting entries that happen to sum to the same total, and only one of them is something a policy did.

The symmetric form matters — a naive p0·q0·(a1−a0) style split leaves a residual that has to be dumped somewhere. These formulae reproduce the annex's forest figures to machine precision, verified against npv-decomposition.csv.

Following the 2 hectares all the way through

One conversion, five accounts, four distinct mechanisms. This single row of the fixture is the most useful regression test in the whole example — if our engine gets forest right, the plumbing is right.

AccountWhat the conversion does to forestOpeningClosingChange
1 · ExtentManaged reduction of 2 ha40 ha38 ha−2 ha
2 · Condition variableForest area density falls as the block loses interior — the C1 landscape variable74%59%−15 pp
2 · Condition indexWeighted ECT aggregate; landscape contributes −0.025 of it0.67070.6118−0.0590
3 · ServicesExpected wood provisioning declines with area and condition150 m³120 m³−30 m³
4 · MonetaryAnnual exchange value of forest's three services$21,000$18,300−$2,700
5 · AssetNPV over a 100-year life at 2%$905,065$788,700−$116,366

Where the balance sheet moves

The closing asset account, by entry type. Note that the total rises even though three of six ecosystem types degrade — revaluation and upward reappraisal more than offset the physical loss. Being able to show that split is much of the point of the standard.

EntryForestLakeCroplandUrbanWetlandSeagrassTotal
Opening value905,0651,078,321484,856522,56851,718529,6793,572,207
Enhancement015,300000015,300
Degradation−108,111000−1,099−163,946−273,156
Conversion · additions0016,94400016,944
Conversion · reductions−43,43500000−43,435
Upward reappraisals0047,70443,0980090,802
Revaluation35,18047,6240215840160,929244,789
Closing value788,7001,141,244549,504565,88151,459526,6623,623,451

Four ways to get this wrong

Each of these is something the standard warns about explicitly, and each is something a naive SQL implementation does by default.

Averaging condition across ecosystem types

Forest and cropland are scored against different reference levels — one natural, one anthropogenic. A mean over both is meaningless (§5.4.1). Condition is reported per ET, full stop.

Summing an intensity, averaging an amount

MSA is a bounded [0,1] index and needs an area-weighted mean. Carbon stock is a per-cell total and needs a sum. The two rules look identical in SQL and produce silently wrong accounts.

Counting intermediate services in the aggregate

A service one ecosystem supplies to another is not part of GEP (§6.2.3). SEEALand has none, which is exactly why it is a poor test of this and real accounts are not.

Treating the NPV change as one number

Without the area / volume / price decomposition you cannot post the entries — conversion, degradation and revaluation are three different lines that happen to sum to the same total.

So what is the assessment actually telling us?

Two hectares of forest became cropland. Here is what the five accounts, read together, say about that — and none of it is visible from any single account on its own.

1. The damage is wildly disproportionate to the area lost

You removed 5% of the forest — 2 hectares of 40. Look at what follows from it:

MeasureOpeningClosingChange
Forest area40 ha38 ha−5%
Forest area density74%59%−15 pp
Expected wood provisioning150 m³120 m³−20%
Expected climate regulation160 tCO₂125 tCO₂−22%

The conversion cut into the block rather than shaving its edge, creating disproportionate perimeter. Forest area density is the single largest contributing variable to the condition decline — −0.025 of the −0.059 total. Nothing else in the account would have caught this, which is precisely why the C1 landscape class earns its place.

2. "Net zero hectares" hides a real loss

The extent account records net change in extent: zero. Two hectares left forest, two hectares joined cropland. But forest is worth $22,627/ha and cropland $8,081/ha, so the swap moves land from a high-value asset class to a low-value one:

Conversion entryValue
Cropland gains (addition)+$16,944
Forest loses (reduction)−$43,435
Net effect of the conversion−$26,491

And that is before the −$108,111 of forest degradation the edge effect helped cause. An area-only account would have called this a wash.

3. The headline number went up while nature got worse

Total asset value rose +$51,244. Split by what actually happened:

ComponentValue
Degradation−273,156
Enhancement+15,300
Conversions, net−26,491
Physical change in natural capital−284,347
Revaluation (prices rose)+244,789
Upward reappraisals+90,802
Price and expectation change+335,591
Net change in value+51,244

Natural capital physically fell by $284,347. The balance sheet rose only because carbon and timber became more valuable. Anyone reporting a single "natural capital value" would have announced good news. This is the strongest argument for the standard's structure: it makes it structurally impossible to book a price rise as an environmental improvement.

How this informs scenarios and policy

The reason to compute accounts rather than indicators is that accounts tell you which lever moved — and therefore which lever to pull.

Siting beats quantity

Because the damage tracks configuration rather than area, the same 2 ha taken from a forest edge versus punched into the interior give materially different outcomes. A scenario engine can rank alternative sitings of an identical development — the actionable lever, and one that falls straight out of the k-ring metric.

Flow and stock fail differently

GEP is an annual flow; the asset account is a stock. You can raise this year's GEP by harvesting more timber while depleting the asset that produces it. Only holding both catches that, which is why the standard refuses to collapse them into one indicator.

Two bad arguments get blocked

"We lost 2 ha of forest but gained 2 ha of cropland, so it's a wash" — no: −$26,491 before induced degradation. And "natural capital is up this year" — no: that was carbon prices.

Where the credibility actually sits

The money moves through the volume effect, and the volume effect is condition. So all of this rests on the account with no agreed reference levels and the thinnest data. That is the honest weak point, and it is where the work should go.

The decomposition names the instrument. Each effect corresponds to a different kind of policy, which is why posting them separately is not bookkeeping pedantry:

EffectAccounting entryPolicy lever
AreaEcosystem conversionZoning, land-use planning
VolumeDegradation / enhancementManagement practice, restoration
PriceRevaluationNot a lever — do not take credit for it

Why this doubles as the scenario engine's test

SEEALand is a scenario: an edit to extent, propagated through every account. Our scenario mechanism does the same thing on real data — the user repaints hexes, stage 1 reruns, and stages 2–5 recompute downstream. Getting the fixture to reproduce exactly means the propagation path is correct before any real layer is trusted, and it stays as the regression test afterwards.

This is why Phase 1 is not blocked on anything. Replicating SEEALand needs no ingest, no catalog layer and no second land-cover date. The data work and the correctness work run in parallel by design.

Read the original

SEEALand is Annex I of the standard — "SEEALand – a stylized example of ecosystem accounting", pp. 369–383 of System of Environmental-Economic Accounting — Ecosystem Accounting (United Nations, 2024 official edition, ST/ESA/STAT/SER.F/124). The complementary spreadsheet with the per-variable workings is published alongside it on the same page.

PageTable / figureWhat it holds
369–370Background, and the general ecological context: the six storylines
370Table AI.1The six ecosystem types, with their IUCN GET codes
371Figures AI.1–AI.2Opening and closing extent maps — the two hectare grids at the top of this page
372Tables AI.2–AI.3Extent account, and the ecosystem type change matrix
373Table AI.4aCondition variable account for forest — stage 2a
374Tables AI.4b–AI.4cCondition indicator and index accounts for forest — stages 2b and 2c
375Table AI.5Condition indices for all six ecosystem types
377–378Tables AI.6–AI.7Physical supply-and-use tables
379–380Tables AI.8–AI.9Monetary supply-and-use tables — GEP appears as total supply
381Table AI.10NPV calculation for forest
383Table AI.11Monetary ecosystem asset account — the closing reconciliation

In this repository. A copy of the standard is at research/seea_ea_final_2024.pdf (Annex I begins on PDF page 402), with a searchable plain-text extraction at research/seea-ea-2024-fulltext.txt from line 21076. The complementary spreadsheet is extracted to CSV in research/seealand-fixture/ — 15 sheets, and the source of every figure quoted on this page. Our distilled summary is research/seea-ea-reference.md §9.

SEEA EA 2024, ST/ESA/STAT/SER.F/124, Annex I, pp. 369–383 Figures verified against research/seealand-fixture/*.csv SQL validated 2026-07-31; latencies per DESIGN.md §10 Layer status per PROVENANCE.md