horizon-shade
Per-pixel × hour × month terrain shade fraction over an AOI from any DEM (default @usgs/3dep/10m). HORAYZON-style: at every pixel walk 360 rays out to 10 km, take the max horizon angle per azimuth bin, and integrate against a NOAA closed-form solar ephemeris over a 15-min-sampled day at the 15th of each month. Output is a single multi-band COG (12 months × N daylight hours), uint8 % shaded. The horizon array is time-invariant — once computed it answers "is the sun blocked here?" for any (date, time) by indexing the solar azimuth bin and comparing solar elevation to the local horizon angle. The recipe produces the per-(hour, month) integrated fraction; downstream consumers who need instant-shade at an arbitrary time can sample the COG band that matches their target (hour, month) pair, or rerun against a finer time grid by overriding `hours` / `samples_per_hour`. Validated against the trail-aligned reference at demos/lake-blanche-shade/: the recipe-driven raster sampled along the Lake Blanche trail points reproduces the published per-point shade fractions (Jun 21 mean within ±3 percentage points). See examples/slc-90min.yaml for the SLC instance and ../products/explore/shared/derived/horizon-shade/README.md for the cross-check record.
The contract
Read from this recipe's own declarations — parameters:,
outputs:, requires:, and the ops its layers name. Not from its
style blocks and not from any benchmark: a colour ramp is not a contract, and a measured
run is evidence about one AOI rather than a domain.
Parameters
The legacy dialect has no typed parameter schema. Read the folia.yaml for what this recipe takes; nothing here can type-check it.
Outputs
| output | kind | layer | what it is |
|---|---|---|---|
primary |
not declared | ['result/shade-fraction', 'compute/sky-view-factor'] |
|
show_your_work |
not declared | ['compute/horizon-grid'] |
|
provenance |
not declared | ['dem_item_ids'] |
Capabilities it requires
The legacy dialect has no requires: block.
Where it runs
- Browser preview does not run here compute/horizon-grid: carries an unsubstituted ${...} template; compute/sky-view-factor: op "terrain_sky_view_factor" has no browser kernel; result/shade-fraction: carries an unsubstituted ${...} template; and 1 more
- Local CLI (folia run) runs here runs locally through the legacy (no spec_version) parser
- Operated fleet (POST /plan, /run) runs here legacy dialect: a lock binds by the cut's layer names, not by digest
registry/recipes/horizon-shade/folia.yaml