Sensor to column, in full
Each chain names the sensor, every processing step between it and the stored value, and the column the result lands in. A chain is what makes an observation auditable: without it a number in obs.capability is a figure with no history.
The chains are recorded in src.element_source.derivation_chain as text, so the processing that produced a value travels with the value rather than living in a script somewhere.
How to read one. Each chain gives you four things. The question in italics is what the element actually answers — not the column name, the physical question. The pipeline runs left to right from source to the coloured output column. The two badges beside the title say how the source meets the grid and how often it can be re-observed. And clicking the pipeline opens what every step does and why it is done that way, ending with where the chain is weakest.
The last part is the point of the tab. Every chain has a step that is a judgement rather than a calculation — a factor fixed because no layer exists, a coefficient awaiting calibration, a proxy standing in for the quantity actually wanted. Those are stated at the foot of each chain rather than left for a reviewer to find.
Grid transferaggregatessource finer than the cell — many pixels reduced to one valuecopy-downsource coarser than the cell — one value written to many cells, which are then not independentRevisitrepeatingre-runnable, supports trendstaticfrozen at one epoch
LQ-T-01Terrain (slope) aggregates 17 px/cell static · 2019COP_DEM_GLO30
How steep is this hectare, as a percentage grade?
GLO-30 elevation▸Reproject to UTM 37N / 38N▸Horn 3×3 gradient▸Convert to percent▸Zonal mean to the 1 ha grid▸slope_pct · %▾ what each step does
1GLO-30 elevationA 30 m grid of surface heights covering the Kingdom.The only openly available elevation model at a resolution finer than the cell.
2Reproject to UTM 37N / 38NConvert from degrees of latitude and longitude to metres.A degree of longitude is about 105 km at Jazan and 93 km at the northern border. Computing a gradient in degrees divides a height in metres by a distance in degrees, which is not a slope.
3Horn 3×3 gradientFit a plane through each pixel and its eight neighbours, and take the steepest direction.Using a 3×3 window rather than two adjacent pixels smooths sensor noise, which would otherwise appear as false steep patches on flat ground.
4Convert to percentrise / run × 100, so a 45° slope reads 100 %.Percent is the unit the capability bands are written in. Degrees and percent are not interchangeable and a source delivering degrees would pass validation while being wrong by a factor of two in the working range.
5Zonal mean to the 1 ha gridAverage the 17 elevation pixels falling inside the cell.Mean rather than maximum: the question is what the hectare is like overall, not whether it contains one steep pixel.
Where this chain is weakestGLO-30 is a surface model, so it includes the tops of buildings and date palms. In cultivated and built-up areas the computed slope is steeper than the ground actually is.
LQ-T-02Water erosion mixed · coarsest 5 km mixed · repeatingmulti-sensor
How much soil would this hectare lose to rainfall in a year, with no conservation measures?
R from CHIRPS rainfall erosivity▸K from SoilGrids texture and SOC▸LS from GLO-30▸C from Sentinel-2 NDVI and WorldCover▸P set to 1▸RUSLE product▸erosion_w_t_ha · t/ha/yr▾ what each step does
1R from CHIRPSRainfall erosivity — how hard the rain falls, not just how much.Erosion depends on intensity. A hundred millimetres in one storm removes far more soil than the same total spread over a season.
2K from SoilGridsSoil erodibility from texture and organic carbon.Sandy, low-carbon soils detach more readily. This is the soil’s own contribution, independent of rain or slope.
3LS from GLO-30Slope length and steepness.Water gains erosive energy as it runs further downhill, so length matters as much as gradient.
4C from Sentinel-2Cover factor from peak NDVI and land cover.Vegetation intercepts rainfall and binds soil. Bare ground erodes at many times the rate of covered ground.
5P set to 1The conservation practice factor is fixed at its maximum.No national terracing or contour-bunding layer exists. Setting P = 1 assumes no practice anywhere.
6RUSLE productA = R × K × LS × C × PThe five factors multiply, so a low value on any one of them holds the whole result down.
Where this chain is weakestWith P fixed at 1 the output is potential erosion under no management. Where terracing exists — the Asir and Al Bahah highlands in particular — actual loss is lower and the figure overstates it.
LQ-T-04Sand encroachment aggregates 150 px/cell 5-day · repeatingSENTINEL2_L2A
How fast is sand advancing across this hectare?
Bare-soil composite per epoch▸Dune-front delineation▸Front displacement between epochs▸Divide by elapsed years▸Zonal mean▸sand_encr_m_y · m/yr▾ what each step does
1Bare-soil composite per epochBuild one cloud-free, vegetation-free image for each of two or more years.A single date can be contaminated by dust or shadow. A composite gives a stable surface to compare against.
2Dune-front delineationTrace the boundary between mobile sand and the surface beyond it in each epoch.Sand and the underlying surface differ in brightness and SWIR response, so the front is detectable spectrally.
3Front displacementMeasure how far the boundary moved between epochs.Encroachment is a rate, so it can only be measured from two observations, never from one.
4Divide by elapsed yearsConvert total displacement to metres per year.Normalising by time makes epochs of different lengths comparable.
5Zonal meanAverage the displacement vectors falling inside the cell.
Where this chain is weakestSentinel-2 begins in 2015, so the longest available baseline is about a decade. Dune movement is episodic rather than steady, and a decade containing one exceptional wind season will read differently from one that does not.
LQ-SC-01Salinity (ECe) aggregates 150 px/cell 5-day · repeatingSENTINEL2_L2A
How salty is the soil in this hectare?
Bare-soil composite▸Salinity indices SI, NDSI, BI▸GSASmap class as prior▸Local calibration▸Zonal mean▸ece_ds_m · dS/m▾ what each step does
1Bare-soil compositeRemove vegetated and water pixels, keep exposed soil.Salinity indices respond to the soil surface. Any vegetation in the pixel corrupts the signal.
2Salinity indices SI, NDSI, BICombine visible and near-infrared bands into indices that respond to surface brightness and salt crust.Salt crusts are brighter and spectrally distinct from unaffected soil in the visible range.
3GSASmap as priorUse the FAO salt-affected class map to constrain the plausible range.The index alone is relative. The prior anchors it to an absolute salinity class.
4Local calibrationFit the index-to-ECe relationship against measured samples.This step cannot currently be performed — no ground samples exist.
5Zonal meanAverage to the cell.
Where this chain is weakestThe chain measures a surface crust, and the capability class is defined on root-zone ECe. Those are correlated but not the same quantity, and without the calibration step the relationship between them is assumed rather than measured. This is why the element is rated proxy-only.
LQ-W-02Flood hazard aggregates annualJRC_GSW + COP_DEM_GLO30
How often is this hectare likely to flood?
GSW occurrence 1984–present▸HAND from GLO-30 drainage network▸Combine occurrence and HAND▸Return-period estimate▸Zonal maximum▸flood_ev_10y · events/10 yr▾ what each step does
1GSW occurrence 1984–presentHow frequently each 30 m pixel has been observed under water over four decades.A long observational record is more reliable than any single flood model.
2HAND from GLO-30Height of each pixel above the nearest drainage channel.A pixel two metres above the wadi bed floods readily; one twenty metres above it does not. HAND captures that without needing hydraulic modelling.
3Combine occurrence and HANDUse observed water where it exists, and terrain position where it does not.Observation alone misses floods that happened between satellite passes. Terrain alone has no evidence behind it. Together they cover each other’s gap.
4Return-period estimateConvert to expected events per ten years.The capability band is written in events per decade.
5Zonal maximumTake the worst-exposed pixel in the cell, not the average.A hectare partly inside a flood path is exposed. Averaging would dilute a real hazard into a comfortable number.
Where this chain is weakestOptical water detection needs a clear view at the moment water is present. Flash floods in wadis drain within hours and are routinely missed entirely.
LQ-W-04Waterlogging risk aggregates 17 px/cell annualJRC_GSW
How many days a year does water stand on this hectare?
GSW seasonality band▸Months of water presence▸Convert to days per year▸Zonal mean▸waterlog_d_y · days/yr▾ what each step does
1GSW seasonality bandA per-pixel count of months in which water was present.Already computed and validated globally, so no reprocessing is required.
2Months of water presenceRead the seasonality value.
3Convert to days per yearScale months to days.The capability band is written in days per year.
4Zonal meanAverage to the cell.
Where this chain is weakestGSW is built for permanent and seasonal water bodies. Ephemeral wadi flow — the dominant surface-water regime across most of the Kingdom — is under-detected, so this element will read low almost everywhere.
SQ-E-01Moisture deficit copy-down · 1 px = 8,100 cells hourly · continuousERA5_LAND
How dry is this hectare, as a ratio of supply to demand?
Total precipitation▸Potential evapotranspiration▸P / PET ratio▸Multi-year mean▸Copy down to the 1 ha grid▸aridity_idx · P/PET▾ what each step does
1Total precipitationAnnual rainfall from reanalysis.Rainfall alone does not define aridity: 100 mm in Tabuk and 100 mm in Jazan support very different agriculture.
2Potential evapotranspirationHow much water the atmosphere would remove if it were available.This is the demand side. Aridity is the balance between the two, not the supply alone.
3P / PET ratioDivide supply by demand.A dimensionless ratio, comparable across the Kingdom and to the international aridity classification.
4Multi-year meanAverage over the baseline period.A single year can be exceptionally wet or dry; the capability class describes the prevailing condition.
5Copy down to the 1 ha gridWrite the 9 km value to each cell inside it.Not an aggregation. One value is written to 8,100 cells, which are then not independent observations of anything.
Where this chain is weakestAt 9 km, the value cannot distinguish a wadi floor from the ridge above it. For a climate element that is often acceptable; it would not be for a soil property.
LQ-C-02Thermal regime copy-down · 1 px = 8,100 cells hourly · continuousERA5_LAND
How much usable heat does this hectare accumulate in a growing season?
2 m temperature, hourly▸Daily mean▸Σ max(0, Tṁₑₐₙ − Tₛₐₛₑ)▸Annual accumulation▸Copy down to the 1 ha grid▸gdd · °C·day▾ what each step does
12 m temperature, hourlyAir temperature at crop height from reanalysis.Surface temperature from thermal satellites is a different quantity and can differ from air temperature by more than ten degrees over bare desert.
2Daily meanReduce hourly values to one per day.
3Σ max(0, Tṁₑₐₙ − Tₛₐₛₑ)Sum the daily excess over a base temperature, treating days below base as zero.Crops accumulate development with warmth above a threshold. Days below it contribute nothing, so they are floored at zero rather than subtracted.
4Annual accumulationTotal over the year.
5Copy down to the 1 ha gridWrite the 9 km value to each cell.
Where this chain is weakestThe base temperature differs by crop, so GDD is not a single number for a cell. It is stored per base temperature, and a cell has as many GDD values as there are distinct base temperatures in the crop library.
LQ-C-03Radiation copy-down · 1 px = 8,100 cells hourly · continuousERA5_LAND
How much solar energy reaches this hectare each day?
Surface solar radiation downwards▸J/m² accumulated → daily total▸Convert to MJ/m²/day▸Multi-year mean▸Copy down to the 1 ha grid▸radiation_mj · MJ/m²/day▾ what each step does
1Surface solar radiation downwardsAccumulated downward shortwave energy from reanalysis.Radiation drives both photosynthesis and evapotranspiration, so it feeds two elements.
2J/m² → daily totalTake the 24-hour accumulation.ERA5-Land accumulates from 00 UTC. Differencing across the day boundary without accounting for the reset produces a negative or doubled value.
3Convert to MJ/m²/dayDivide by 10⁶.MJ/m²/day is the unit used in FAO-56 and in the capability bands.
4Multi-year meanAverage over the baseline.
5Copy down to the 1 ha gridWrite the 9 km value to each cell.
Where this chain is weakestRadiation varies little across short distances, so the 9 km resolution costs less here than it does for any other element sourced from ERA5-Land.
SQ-E-04Length of growing period copy-down · coarsest 9 km daily · continuousERA5_LAND + CHIRPS
How many days a year can a crop actually grow here?
Daily precipitation from CHIRPS▸PET from ERA5-Land▸Days where P > 0.5 × PET▸Add soil-moisture carry-over▸Annual count▸lgp_days · days▾ what each step does
1Daily precipitation from CHIRPSRainfall at 5 km, finer than the reanalysis.Precipitation varies over shorter distances than temperature, so the finer source is worth the extra step.
2PET from ERA5-LandAtmospheric demand.
3Days where P > 0.5 × PETCount days where rainfall meets at least half the demand.The convention treats a day as growing when supply is within reach of demand, not only when it exceeds it.
4Add soil-moisture carry-overExtend the period while stored soil water remains available.Growth continues after rain stops. Ignoring carry-over would end every growing period at the last wet day.
5Annual countTotal growing days.
Where this chain is weakestThe 0.5 coefficient and the carry-over term are registered for calibration. Both change the answer materially and neither is settled.
LQ-SP-03Rooting conditions copy-down · 1 px = 6.2 cells static · 2020SOILGRIDS_250
How deep can roots go before something stops them?
bdricm depth to bedrock▸cfvo coarse fragments 0–100 cm▸Constrain depth by fragment content▸Copy down to the 1 ha grid▸rooting_depth_cm · cm▾ what each step does
1bdricm depth to bedrockModelled depth to a root-restricting layer.A prediction from a global model, not a measurement. The uncertainty is published alongside it.
2cfvo coarse fragmentsVolumetric gravel and stone content by horizon.Soil can be deep and still unrootable if it is largely stone.
3Constrain depth by fragment contentReduce the effective depth where fragments are high.The stored value is effective rooting depth, not depth to bedrock.
4Copy down to the 1 ha gridOne 250 m pixel covers 6.2 cells.Four adjacent cells share one modelled value, so they agree with each other by construction rather than by observation.
Where this chain is weakestSoilGrids is a model trained largely on profiles from wetter regions. Arid-zone predictions carry higher uncertainty, and the uncertainty layers should be carried through rather than discarded.
SQ-A-05Soil texture copy-down · 1 px = 6.2 cells static · 2020SOILGRIDS_250
What is the soil texture class of this hectare?
sand, silt, clay by horizon▸Weight to 0–100 cm▸USDA texture triangle▸Copy down to the 1 ha grid▸texture_class · category▾ what each step does
1sand, silt, clay by horizonThree modelled fractions at six standard depths.
2Weight to 0–100 cmDepth-weight the fractions into a single profile value.Weighting the fractions and classifying once is not the same as classifying each horizon and taking a majority — the two give different answers.
3USDA texture triangleMap the three fractions to one of twelve classes.A standard, published classification, so the output is interpretable outside this study.
4Copy down to the 1 ha grid
Where this chain is weakestA texture class is categorical, so no averaging is possible downstream. Once assigned it can only be replaced.
SQ-E-05Frost risk copy-down · 1 px = 8,100 cells hourly · continuousERA5_LAND
How often does frost threaten a crop here?
2 m minimum temperature, daily▸Days below crop killing temperature▸Annual count▸Copy down to the 1 ha grid▸frost_days · days/yr▾ what each step does
12 m minimum temperature, dailyDaily minima from reanalysis.Frost damage depends on the minimum reached, not the daily mean.
2Days below killing temperatureCount days under the crop-specific threshold.The threshold comes from the crop requirement table, so the count differs by crop.
3Annual count
4Copy down to the 1 ha grid
Where this chain is weakestFrost forms in valley bottoms through cold-air drainage, at scales of hundreds of metres. A 9 km grid cannot resolve this at all — and the Asir and Al Bahah highlands, where frost actually matters, are precisely where the terrain is most broken. Station records would materially improve this element.
SQ-F-01Irrigation demand copy-down · 1 px = 8,100 cells hourly · continuousERA5_LAND
How much irrigation water does a given crop need on this hectare?
Temperature, humidity, wind, radiation▸FAO-56 Penman-Monteith ET₀▸× crop K₋ by growth stage▸Sum over season▸etc_m3_ha · mm/season▾ what each step does
1Temperature, humidity, wind, radiationThe four drivers of evaporative demand.FAO-56 requires all four. Omitting wind or humidity biases the result in arid conditions specifically.
2FAO-56 Penman-Monteith ET₀Reference evapotranspiration for a standard grass surface.An international standard, so the figure is comparable and auditable.
3× crop K₋ by growth stageScale by the crop coefficient for each stage of the season.A crop uses far less water at emergence than at full canopy. A single seasonal coefficient would misstate both ends.
4Sum over seasonTotal seasonal requirement.
Where this chain is weakestThis is the only chain whose output depends on the crop, so it is stored per crop rather than per cell. It is also the chain most exposed to the 9 km resolution, because irrigation demand is what an investment case turns on.
Several numbers on this page are thresholds. The NDVI cut-off that defines bare soil, the cloud-probability cut-off, the minimum number of clear observations per composite — each one changes which pixels contribute to a stored value, and therefore changes the value. They are registered for expert calibration exactly as class boundaries are, and are stated here as working figures rather than settled ones.
1 · Cloud, cirrus and dustSentinel-2 L2A carries a scene classification layer. Classes 3 (cloud shadow), 8 and 9 (cloud, medium and high probability), 10 (thin cirrus) and 11 (snow and ice) are masked. The s2cloudless probability layer is applied in addition, because SCL under-detects thin cloud edges.
Dust is the harder problem, and it is the one that matters here. Suspended dust raises reflectance across the visible bands without producing the sharp thermal and geometric signature that cloud detection relies on, so SCL frequently passes a dust-affected scene as clear. Over the Kingdom this is not an edge case — it is a recurring seasonal condition. The aerosol optical thickness band delivered with L2A is used as a secondary screen, and scenes above the AOT cut-off are dropped even where SCL reports clear sky.
Sentinel-1 is unaffected by both, which is why SAR carries the water-detection chains where optical coverage is unreliable.
2 · Temporal compositingSingle-date imagery is not used for any element. Every optical chain runs on a composite.
Bare-soil composite. Pixels are selected where NDVI falls below the bare-soil cut-off and no water is detected, then reduced by median across a multi-year window. Median rather than mean, because a single undetected dust or cloud pixel moves a mean and does not move a median. Across most of the Kingdom vegetation is sparse enough that bare-soil pixels are abundant; in the Asir and Jazan highlands they are not, and the composite there rests on fewer observations.
Peak-vegetation composite. Maximum NDVI over the same window, used for the RUSLE C-factor and for detecting cultivated land.
Every composite records its observation count per cell. A cell built from three clear scenes and a cell built from sixty are not the same measurement, and the count is what allows that to be visible later rather than assumed away.
3 · Normalising every source to the hectare cellSources arrive at seven different resolutions, from 10 m to 9 km, and every one has to end up as a single value on a 10,000 m² hexagon. There is no universal resampling step that does this correctly, because two fundamentally different operations are involved and confusing them is the most common way to produce a plausible-looking wrong answer.
Which operation applies is decided by one comparison: the source pixel against the 107.46 m across-flats width of the cell.
Source pixelOperationPixels per cellCells per pixelWhat the cell value actually is
10 m — Sentinel-2aggregate100.0—A statistic over 150 real observations of this hectare.
20 m — S2 SWIRaggregate25.0—A statistic over 38 observations. Any index using B11 or B12 lands here, not at 10 m.
30 m — DEM, GSWaggregate11.1—A statistic over 17 observations. Thin enough that weighting method changes the answer.
250 m — SoilGridscopy-down—4.2One source value written to 4 cells. They agree by construction, not by observation.
1 km — MODIScopy-down—100.0One value across 66 cells.
5 km — CHIRPScopy-down—2,500One value across 2,500 cells.
9 km — ERA5-Landcopy-down—8,100One value across 8,100 cells — roughly 81 km² of identical output.
3.1 · The procedure, step by stepWhat an analyst actually runs, in order. Steps 1 to 3 are common to both operations; step 4 branches.
1Generate the cell geometry, not a raster gridProduce the cell identifieres covering the area of interest and their boundary polygons. In PostgreSQL with PostGIS: grid.cells_in(boundary) then grid.cell_boundary(cell_id). The cells are the analysis unit from this point forward — the raster is never resampled to a regular 131 m grid, because a hexagon is not a square and forcing one through the other resamples twice.
2Move the vectors to the raster, not the raster to the vectorsTransform the cell polygons into the raster’s native CRS. Do not reproject the raster. Reprojecting a raster resamples every pixel and introduces interpolation error before any analysis has happened; transforming a few million polygon vertices is exact.The exception is slope and any other gradient or area computation, which must run in UTM 37N or 38N. There the DEM is reprojected once, deliberately, and that is a documented cost.
3Mask invalid pixels firstApply the cloud, cirrus, shadow and AOT masks from section 1 before any statistic is computed. A masked pixel must be excluded from the denominator, not treated as zero — the difference is the whole reason a cell can report a valid mean on partial coverage.
4Aggregate, or copy down — never both, never interpolateIf the pixel is finer than 107.46 m, compute an area-weighted statistic over the pixels intersecting the cell. If it is coarser, assign the value of the pixel containing the cell centroid.A coarse raster is never bilinearly resampled to a finer grid before this step. That produces values which exist nowhere in the source and gives 8,100 cells the appearance of independent detail.
5Use exact area weighting, not pixel centroidsA pixel counts in proportion to the area it shares with the cell. The common shortcut — include a pixel if its centroid falls inside the polygon — is acceptable at 10 m and materially wrong at 30 m. See 3.3.
6Record coverage alongside the valueStore the number of contributing pixels and the fraction of the cell covered by valid data. A cell computed from 4 clear pixels and one computed from 150 are not the same measurement, and only the recorded count makes that visible later.
7Apply the coverage gate, then write NULLBelow the minimum valid-coverage fraction the cell is written NULL. It is never filled from neighbouring cells. A gap recorded as unknown is handled correctly by the confidence model; a gap filled by interpolation becomes an assumption the model cannot detect.
3.2 · Ingestion pattern and statistic, element by elementNot every element is a raster. Four ingestion patterns are in use and they are not interchangeable — choosing the wrong one produces a value that loads cleanly and is wrong in a way nothing downstream detects.
PatternElementsWhen it applies, and the rule that governs it
aggregate10Raster finer than the cell. An area-weighted statistic over the pixels intersecting the hexagon. The statistic itself depends on the variable — see the table below.
copy-down21Raster coarser than the cell. The value of the pixel containing the cell centroid, with no smoothing and no blending. The largest group.
vector overlay14Polygon sources. Categorical attributes take the majority by area; legal constraints take any intersection, which is the single most important distinction on this page.
point interpolation11Point sources — the SWA well network. Most values belong to the serving well and are assigned, not interpolated. Only the water-level trend is a genuine continuous field.
crop table1Not spatial. Joined from the crop library at classification time.
blocked9No statistic can be specified until the index construction is defined.
The distinction that matters most is majority-by-area against any-intersection. A protected-area polygon covering 49 % of a hectare would leave that hectare unconstrained under a majority rule. For the six legal checks the rule is any intersection — a hectare partly inside a reserve is constrained — while for descriptive polygons such as lithology or aquifer type the majority is correct. The two rules look similar in code and give opposite answers on the cells that matter.
All 64 elementsColumn, data type, source, pattern and statistic for every assessed element, with the reason. This is the ingestion specification: a developer should be able to build the extraction for any element from its row alone.
ElementNameColumnTypeSourcePatternStatisticWhy
LQ-SP-01Available water capacityawc_mm_mnumericSoilGrids 250 mcopy-downcentroid pixelCoarser than the cell, so no aggregation is possible. One value serves 6.2 cells.
LQ-SP-02Soil workabilityworkability_idxnumericSoilGrids 250 mblocked—Index construction undefined. No statistic can be specified until the scale is.
LQ-SP-03Rooting conditionsrooting_depth_cmnumericSoilGrids 250 mcopy-downcentroid pixelAs above. The depth-restriction constraint is applied per pixel before transfer, not after.
LQ-SP-04Surface sealing and crustingsealing_idxnumericSoilGrids 250 mblocked—Index construction undefined.
LQ-SC-01Salinity (ECe)ece_ds_mnumericGSASmap 1 km + S2 10 mcopy-downcentroid pixel, refined by area-weighted mean of the S2 indexTwo-stage: the class prior is copy-down, the within-class refinement aggregates. The coarser source governs the resolution score.
LQ-SC-02Sodicity (ESP)esp_pctnumericGSASmap 1 kmcopy-downcentroid pixelClass map, so the cell inherits the class midpoint of the pixel containing it.
LQ-SC-03Nutrient availabilitynutrient_idxnumericSoilGrids 250 mblocked—Index construction undefined.
LQ-SC-04Toxicity (boron)boron_mg_lnumericGLiM lithology, vectorvector overlaymajority by areaA lithology polygon is categorical. The unit covering most of the cell supplies the expected parent-material value.
LQ-W-01Drainage conditiondrainage_classtextHWSD v2 polygonvector overlaymajority by areaResolved. The HWSD drainage class is read directly rather than reduced to an index — drainage is conventionally a class, not a score. Categorical, so the unit covering most of the cell supplies the value.
LQ-W-02Flood hazardflood_ev_10yintegerJRC GSW 30 m + DEMaggregatemaximumA hectare partly inside a flood path is exposed. A mean would dilute a real hazard into a comfortable number.
LQ-W-04Waterlogging riskwaterlog_d_yintegerJRC GSW 30 maggregatearea-weighted meanDuration accumulates over the whole hectare rather than being set by its worst pixel.
LQ-T-01Terrain (slope)slope_pctnumericCopernicus DEM 30 maggregatearea-weighted meanThe question is what the hectare is like overall. Exact weighting is mandatory here — 70 % of the cell lies within one pixel of its boundary.
LQ-T-02Water erosionerosion_w_t_hanumericRUSLE, coarsest input 5 kmaggregatearea-weighted mean of the per-pixel RUSLE resultCompute RUSLE per pixel, then aggregate. Aggregating the five factors first and multiplying the cell means gives a different and wrong answer, because the product of means is not the mean of products.
LQ-T-03Wind erosionerosion_wind_t_hanumericRWEQ, coarsest input 9 kmaggregatearea-weighted mean of the per-pixel RWEQ resultResolved. RWEQ produces t/ha/yr — the same unit as water erosion, so the two hazards are directly comparable. Compute per pixel then aggregate, as for LQ-T-02.
LQ-T-04Sand encroachmentsand_encr_m_ynumericSentinel-2 10 maggregate95th percentileEncroachment is driven by the advancing front, not the cell average — but a maximum would be set by a single mis-registered pixel, so the percentile guards against that.
LQ-C-02Thermal regimegddintegerERA5-Land 9 kmcopy-downcentroid pixelGDD is accumulated per pixel across the year before transfer. One value serves 8,100 cells.
LQ-C-03Radiationradiation_mjnumericERA5-Land 9 kmcopy-downcentroid pixelAs above. Radiation varies little over short distances, so the cost of copy-down is lowest here.
WP-A-01Source typesource_typetextSWA well register, pointspoint interp.nearest well within the service radiusCategorical, so no interpolation is possible. Beyond the radius the cell is NULL, not the nearest value at any distance.
WP-A-02Available volumeavail_vol_m3_hanumericSWA + SGSpoint interp.licensed volume of the serving well ÷ its service areaAn allocation, not a field. It is divided among the cells it serves rather than interpolated between wells.
WP-A-03Distance to sourcedist_source_kmnumericSWA well pointspoint interp.Euclidean distance to the nearest wellA computed geometry, not a sampled variable. Exact per cell.
WP-B-01Water-level trendlevel_trend_m_ynumericSWA monitoring networkpoint interp.IDW or kriging over the monitoring networkA continuous field sampled at points. Interpolation is legitimate here and nowhere else in the water module — and the interpolation error must be carried into σ for confidence component 3.
WP-B-02Aquifer typeaquifer_typetextSGS hydrogeology, vectorvector overlaymajority by areaCategorical polygon.
WP-B-03Remaining supply horizonsupply_horizon_ynumericSWA + SGSpoint interp.computed per cell from interpolated level and saturated thicknessDerived from two interpolated fields; the error compounds and should be recorded as such.
WP-C-01Irrigation water salinityecw_ds_mnumericSWA quality recordspoint interp.value of the serving wellA property of the water supplied, not of the location. Interpolating between wells would invent a supply that nobody uses.
WP-C-02Sodium adsorption ratiosarnumericSWA quality recordspoint interp.value of the serving wellAs above.
WP-C-03Chloridechloride_mg_lnumericSWA quality recordspoint interp.value of the serving wellAs above.
WP-C-04Boron in irrigation waterboron_w_mg_lnumericSWA quality recordspoint interp.value of the serving wellAs above.
WP-C-05Treated wastewater tierww_tiertextSWA plant registerpoint interp.tier of the serving plant, NULL where the source is not treated wastewaterCategorical and conditional on WP-A-01.
WP-D-01Pumping liftpump_lift_mnumericSWA + DEM 30 mpoint interp.interpolated water level subtracted from the DEM cell meanCombines an interpolated field with an aggregated raster. Both errors carry forward.
WP-D-02Conveyance distanceconveyance_kmnumericSWA network, vectorvector overlaynetwork distance to the nearest offtakeNetwork distance, not Euclidean — a canal does not run in a straight line.
WP-E-01Basin sustainable yieldbasin_yield_mm3numericMEWA basin determinationvector overlayvalue of the containing basin polygonA basin-level determination. Every cell in the basin carries the same value by definition, and that is correct rather than a limitation.
WP-E-02Allocation statusalloc_pctnumericMEWA licensingvector overlayvalue of the containing basin polygonAs above.
EPProtected areaep_protectedtextNCW register, vectorvector overlayany intersectionA legal constraint, not a measurement. If any part of the hectare falls inside a protected area, the hectare is constrained. Majority-by-area would clear a cell that is 49 % inside a reserve.
EVRangeland, forest and afforestationev_rangelandtextNCVC register, vectorvector overlayany intersectionAs above.
ETTenureet_tenuretextMOJ Watheeq, vectorvector overlayany intersection, worst state winsWhere a cell spans several parcels it takes the most restrictive tenure state present.
EZZoning designationez_zoningtextMOMAH scheme, vectorvector overlayany intersection, worst state winsAs above.
EXConflicting useex_conflictingtextMEWA / MOE / MOD / MODONvector overlayany intersectionA single overlapping designation constrains the whole hectare.
EHHazard designationeh_hazardtextNCEC mapping, vectorvector overlayany intersection, highest severity winsAs above.
SQ-A-01Available water capacityawc_mm_mnumericSoilGrids 250 mcopy-downcentroid pixelSame ingestion as LQ-SP-01 — the measurement is identical, only the rating differs.
SQ-A-02Soil workabilityworkability_idxnumericSoilGrids 250 mblocked—Same ingestion as LQ-SP-02 — the measurement is identical, only the rating differs.
SQ-A-03Rooting conditionsrooting_depth_cmnumericSoilGrids 250 mcopy-downcentroid pixelSame ingestion as LQ-SP-03 — the measurement is identical, only the rating differs.
SQ-A-04Surface sealing and crustingsealing_idxnumericSoilGrids 250 mblocked—Same ingestion as LQ-SP-04 — the measurement is identical, only the rating differs.
SQ-B-01Salinity (ECe)ece_ds_mnumericGSASmap 1 km + S2 10 mcopy-downcentroid pixel, refined by area-weighted mean of the S2 indexSame ingestion as LQ-SC-01 — the measurement is identical, only the rating differs.
SQ-B-02Sodicity (ESP / SAR)esp_pctnumericGSASmap 1 kmcopy-downcentroid pixelSame ingestion as LQ-SC-02 — the measurement is identical, only the rating differs.
SQ-B-04Toxicity risk (boron)boron_mg_lnumericGLiM lithology, vectorvector overlaymajority by areaSame ingestion as LQ-SC-04 — the measurement is identical, only the rating differs.
SQ-C-01Drainage conditiondrainage_classtextHWSD v2 polygonvector overlaymajority by areaSame ingestion as LQ-W-01 — the measurement is identical, only the rating differs.
SQ-C-02Flood hazardflood_ev_10yintegerJRC GSW 30 m + DEMaggregatemaximumSame ingestion as LQ-W-02 — the measurement is identical, only the rating differs.
SQ-C-03Waterlogging riskwaterlog_d_yintegerJRC GSW 30 maggregatearea-weighted meanSame ingestion as LQ-W-04 — the measurement is identical, only the rating differs.
SQ-D-01Terrain workabilityslope_pctnumericCopernicus DEM 30 maggregatearea-weighted meanSame ingestion as LQ-T-01 — the measurement is identical, only the rating differs.
SQ-D-02Water erosion hazarderosion_w_t_hanumericRUSLE, coarsest input 5 kmaggregatearea-weighted mean of the per-pixel RUSLE resultSame ingestion as LQ-T-02 — the measurement is identical, only the rating differs.
SQ-D-03Wind erosion hazarderosion_wind_t_hanumericRWEQ, coarsest input 9 kmaggregatearea-weighted mean of the per-pixel RWEQ resultSame ingestion as LQ-T-03 — the measurement is identical, only the rating differs.
SQ-D-04Sand encroachment hazardsand_encr_m_ynumericSentinel-2 10 maggregate95th percentileSame ingestion as LQ-T-04 — the measurement is identical, only the rating differs.
SQ-E-02Thermal suitabilitygddintegerERA5-Land 9 kmcopy-downcentroid pixelSame ingestion as LQ-C-02 — the measurement is identical, only the rating differs.
SQ-E-03Radiation and solar energyradiation_mjnumericERA5-Land 9 kmcopy-downcentroid pixelSame ingestion as LQ-C-03 — the measurement is identical, only the rating differs.
SQ-E-01Moisture deficit (aridity)aridity_idxnumericGlobal AI/PET 1 kmcopy-downcentroid pixelRated against the crop’s water demand, not as a land property. One value serves 100 cells.
SQ-E-04Length of growing periodlgp_daysintegerERA5-Land 9 kmcopy-downcentroid pixelThe thermally possible season, counted per pixel from the daily series, then transferred. Not the rainfed season — that reads zero across almost the whole Kingdom.
SQ-A-05Soil texturetexture_classtextSoilGrids 250 mcopy-downcentroid pixel, classified after depth weightingDepth-weight the sand, silt and clay fractions first, then apply the USDA triangle once. Classifying each horizon and taking a majority gives a different class.
SQ-A-06Coarse fragmentscoarse_frag_pctnumericSoilGrids 250 mcopy-downcentroid pixel
SQ-B-05Calcium carbonatecaco3_pctnumericHWSD v2 polygonvector overlayarea-weighted meanA polygon attribute, so within-polygon variation is already lost. Area weighting handles cells spanning two mapping units.
SQ-B-06Gypsum contentgypsum_pctnumericHWSD v2 polygonvector overlayarea-weighted meanAs above. High null rate expected — national gypsum mapping is incomplete, and uncovered cells are written NULL rather than zero.
SQ-B-07Soil pHph_h2onumericSoilGrids 250 mcopy-downcentroid pixelpH is logarithmic. Where any averaging occurs it must be on hydrogen-ion concentration, not on pH units.
SQ-E-05Frost riskfrost_daysintegerERA5-Land 9 kmcopy-downcentroid pixelCounted per pixel from the daily minima, then transferred. The resolution is coarser than the process being measured.
SQ-F-01Irrigation demand (ETc)etc_m3_hanumericERA5-Land 9 kmcopy-downcentroid pixel, × crop K₋ET₀ is computed per pixel and transferred; the crop coefficient is applied afterwards, per crop.
SQ-F-02Crop nutrient requirementnutrient_req_idxnumericALUES crop tablecrop tablelookup by cropNot a spatial variable at all. It is a property of the crop, joined at classification time.
Three rows carry a trap worth reading before writing any code. LQ-T-02 water erosion must be computed per pixel and then aggregated — aggregating the five RUSLE factors first and multiplying the cell means gives a different answer, because the product of means is not the mean of products. SQ-B-07 soil pH is logarithmic, so any averaging must happen on hydrogen-ion concentration rather than on pH units. And SQ-A-05 soil texture must be depth-weighted first and classified once — classifying each horizon and taking a majority gives a different class.
3.3 · Why exact weighting matters more than it looksA hexagon of 10,000 m² has an apothem of 65.7 m. The share of its area lying within one pixel-width of its boundary — that is, the share covered by pixels that straddle the edge — is:
Pixel sizeArea within one pixel of the edgeConsequence
10 m33.8 %Centroid-in-polygon is a tolerable approximation. Roughly 42 of 150 pixels straddle the edge.
20 m60.6 %Half the cell is edge. Weighting method starts to change the second decimal.
30 m80.5 %Four-fifths of the cell is within one pixel of its boundary. With only 17 pixels in the cell, nearly every one is shared with a neighbour. Centroid inclusion here produces visible hexagonal artefacts in slope.
This is a consequence of hexagons having a high perimeter-to-area ratio at this size, and it is why the pipeline uses exact polygon-raster intersection — exactextract, or reduceRegions with a weighted reducer in Earth Engine — rather than the faster centroid test. At 30 m the two methods disagree enough to move cells across a class boundary.
3.4 · Copy-down: what is and is not permittedRules for sources coarser than the cell
AssignmentThe cell takes the value of the pixel containing its centroid. Where a cell straddles two source pixels, the centroid decides — a boundary in the source stays a hard boundary in the output.
No smoothingThe source is not bilinearly or cubically resampled to a finer grid first. That would blur the pixel boundary into a gradient that does not exist in the data, and would give every cell a slightly different value — the appearance of hectare-level detail with none behind it.
No area-weighted blendAveraging the two or four source pixels a cell touches was considered and rejected: it produces values present nowhere in the source, and it is indistinguishable in the output from a genuine measurement.
Recorded, not hiddenThe cells-per-pixel ratio is carried into conf.element_confidence as the resolution score. This is the only mechanism preventing a copy-down value from being read as an independent observation of the cell.
Downstream consequenceAdjacent cells sharing a source pixel are not independent samples. Any spatial statistic computed over them — variance, autocorrelation, a confidence interval on an area figure — will be inflated unless the effective sample size is corrected to the number of source pixels rather than the number of cells.
3.5 · Two implementation routesEither is acceptable; the choice is operational
Cloud — Earth EngineCells uploaded as a FeatureCollection, then image.reduceRegions(collection, reducer, scale) with scale set to the source’s native resolution. Setting scale to anything other than the native resolution silently resamples, which is the most common error in this workflow. Export as CSV keyed on the cell identifier.
Local — GDAL and exactextractCell polygons as GeoParquet in the raster CRS, then exactextract for area-weighted statistics, writing directly to the obs.* table keyed on cell_id. Slower to set up, fully reproducible, and it keeps the province partitioning intact through the load.
Not recommendedPostGIS raster with ST_Clip and ST_SummaryStats per cell. Correct, but at 215 M cells the per-cell overhead makes a national run impractical.
Whichever route is used, the output must carry four things per cell: the cell identifier, the value, the count of valid contributing pixels, and the source identifier. A value without its pixel count cannot be given a completeness figure, and a value without its source cannot be traced, revised or superseded. Both are columns that already exist in obs.* and src.element_source — they are not additions to be negotiated at load time.
4 · ProjectionAll area and gradient operations run in UTM zone 37N (EPSG:32637) or 38N (EPSG:32638). The national extent spans both zones, so cells are assigned by longitude and the two halves are processed separately.
Results are stored in EPSG:4326. Slope, erosion and any area figure computed in geographic coordinates would be wrong by a factor that varies with latitude across the Kingdom, so no such operation is performed before reprojection.
5 · What is recorded alongside every valueWritten to src.element_source and obs.*
derivation_chainThe full chain as text, in the form shown on the first tab.
processing_noteCompositing window, masking applied, gap-filling method.
obs_dateThe reference date of the source data, not the load date. A 2019 DEM loaded in 2026 is a 2019 observation.
source_set_idWhich combination of layers produced the row, so a rebuild with different inputs is distinguishable from the original.
completenessHow many of the module’s elements are populated on the cell. Drives the confidence flag on the result.