Repository navigation
perf(analysis): hillshade is made and written as bytes (#1111) - #1887
Conversation
A hillshade from Raster Functions, or a function chain ending in one, is made as an 8-bit raster: shades 1-255, with 0 for no data, so a cell in full shadow is 1 instead of 0. It is still drawn as a grey stretch on the raster defaults, not as classes when it holds few shades. The untiled GeoTIFF writer writes an 8-bit grey band of whole bytes as bytes (an empty cell only where no-data marks it), as the COG writer already did, so such an export and the copy a project keeps are a quarter of the size. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
Code reviewBugs. None found. I checked the untiled byte path's no-data handling: Security. None. The new code adds no input parsing; parameters go through the existing Performance. No defect. The byte branch makes two passes over the band (the Quality (nits; I left these for the release quality pass and did not post inline comments):
AGENTS.md. Compliant on the points I checked:
One claim I could not verify offline: the PR says a 1–255 shade range with 0 as no-data "is the convention other tools' hillshades use". Before merge, the PR should cite the tool or soften the wording. Confidence in the claim being wrong: low. Earlier review threads: none ( Change sizeCompared with the base branch (merge base d39c16e to PR head 523e6e6), covering the whole PR.
|
|
📖 Docs preview
GitHub Pages takes a minute or two to publish a new commit. Newer commits from the fork aren't published until a maintainer adds the |
Summary
Second item of step 4 of #1111: Hillshade writes Byte. A hillshade's values are whole numbers 0–255, but it was made and written as 32-bit floats.
raster.functionwith"function": "hillshade", andraster.functionChainwhen its last step is one, now make an 8-bit (UInt8) raster. Its shades run 1–255 and 0 marks no data: a cell in full shadow is 1 instead of 0, and every lit cell keeps its value. GDAL'sgdaldem hillshadewrites the same: bytes, shades from 1 and 0 as no-data, so the file reads the same there. A step after a hillshade in a chain reads its no-data and makes floats as before.share.exportRasterwithoutcog, and the copy of a made raster a project keeps) wrote every single grey band as 32-bit floats, so a byte raster's file was four times its size. It now writes bytes when the raster isUInt8, every value is a whole number 0–255, and an empty cell occurs only where the no-data value can mark it. Otherwise it writes floats as before. This applies to any 8-bit grey raster, not only hillshades; the values read back unchanged.A COG of a hillshade holding 64 or fewer distinct shades counts as classes for the COG writer, so its overviews take a pixel instead of an average. A hillshade of a real elevation model holds far more shades than that.
Measured on the 9667 × 11947 elevation model: to follow in this description.
Testing
rasterops::tests::hillshade_keeps_zero_for_no_data: a cell in full shadow is 1, and the bytes made of it areUInt8with 0 for the no-data cell.geotiff::tests::grey_bytes_round_trip_as_bytes: an 8-bit grey band reads back asUInt8with its no-data. A band with an unmarked empty cell, or with a fraction, stays Float32.tests::hillshade_is_made_and_written_as_bytes: Raster Functions and a chain ending in a hillshade makeUInt8layers drawn as a stretch, including a single-shade plane. A step after a hillshade honours its no-data. The plain and COG exports read back asUInt8with the same values.-D warnings, the workspace tests andlayers, wasm, licences) on the fork at 523e6e6: pass (run)UI evidence
No visible UI change: the hillshade layer is drawn with the same stretch as before.
Related issue
Part of #1111
🤖 Generated with Claude Code
Summary by CodeRabbit