rasterintro(1)

πŸ¦‹ Raster data processing in GRASS GIS πŸ’–

hiiii bestie, welcome to rasterintro(1), aka the GRASS GIS User's Manual page that explains literally everything about how raster data works in GRASS. this is the big-picture vibe page β€” the one you read before you go touching any r.* module. grab a snack, it's a long one πŸ“


🌸 Raster maps in general 🌸

so, a "raster map" is a data layer made of a gridded array of cells. it has a certain number of rows and columns, and in every single cell there's either a data point or a null value indicator (the "nothing here" signal, no cap). these can exist as a plain 2D grid, or as a 3D cube made up of a whole stack of smaller cubes β€” like a stack of 2D grids, one on top of another. it's giving layered cake πŸŽ‚

the geographic boundaries of the raster map are described by the north, south, east, and west fields. these values describe the lines that bound the map at its edges. and here's the important bit, bestie β€” those lines do NOT pass through the centre of the grid cells at the edge of the map, they run along the edge of the map itself. i.e. the geographic extent of the map is described by the outer bounds of all cells within the map. so the boundary hugs the outside of the outermost cells, not their middles. periodt πŸ’…

now, the general rules of GRASS GIS, and these are iconic so write them down:

  1. Raster output maps have their bounds and resolution equal to those of the current computational region.
  2. Raster input maps are automatically cropped/padded and rescaled (using nearest-neighbour resampling) to match the current region.
  3. Raster input maps are automatically masked if a raster map named MASK exists. the MASK is only applied when reading maps from the disk.

but ofc there are exceptions, because there's always a plot twist 😭

  • the r.in.* programs read the data cell-for-cell, with no resampling. when you're reading non-georeferenced data, the imported map will usually have its lower-left corner at (0,0) in the project's coordinate system β€” and then you, my dear, need to use r.region to "place" the imported map where it actually belongs.
  • some programs that need to do their own special types of resampling (e.g. r.resamp.rst) read the input maps at their original resolution and then do the resampling themselves. main character behaviour, honestly.
  • r.proj has to juggle two regions at the same time β€” source and destination β€” and both of them will have an impact upon the final result. it's carrying a lot, be nice to it 🫢

πŸŽ€ Raster import and export πŸŽ€

the module r.in.gdal offers a common interface for many different raster formats. on top of that, it also gives you options like on-the-fly project creation, or extending the default region to match the extent of the imported raster map. for special cases there are other import modules available too. and important: the full map is always imported. no half-measures ✨

for importing scanned maps, here's the little ritual you have to do: the user needs to create an x,y-project, scan the map at the desired resolution, save it into an appropriate raster format (e.g. tiff, jpeg, png, pbm), and then use r.in.gdal to import it. based on reference points, the scanned map can be rectified to obtain geocoded data. glow-up complete πŸ’…

raster maps get exported with r.out.gdal into common formats. you also have r.out.bin, r.out.vtk, r.out.ascii and other export modules available. these export the data according to the current region settings. if those settings differ from the original map, the map gets resampled on the fly (using the nearest neighbor algorithm). in other words: the output will have as many rows and columns as the current region. no cap.

so if you want to export maps with various grid spacings (e.g. 500x500 or 200x500), you can just change the region resolution with g.region and then export the map. the resampling is done with the nearest neighbor algorithm in this case. but if you want some other form of resampling: first change the region, then explicitly resample the map with e.g. r.resamp.interp or r.resamp.stats, and then export the resampled map. order matters, bestie πŸ¦‹

swapping GRASS GIS raster maps between different projects that share the same CRS can be done in a lossless way using the r.pack and r.unpack modules. chef's kiss πŸ‘‘


⭐ Metadata ⭐

the r.info module shows you general info about a map β€” region extent, data range, data type, creation history, and other metadata. so basically the map's whole backstory πŸ’–

metadata like map title, units, vertical datum etc. can be updated with r.support. timestamps are managed with r.timestamp. and region extent + resolution are managed with r.region. three little modules, three little jobs, so organized ✨


πŸ”₯ Raster map operations πŸ”₯

🌈 Resampling methods and interpolation methods 🌈

GRASS raster map processing is always performed in the current region settings (see g.region) β€” i.e. the current region extent and current raster resolution are what's used, always. if the resolution differs from that of the input raster map(s), then on-the-fly resampling happens (nearest neighbor resampling). and if you do not want that? then the input map(s) has/have to be resampled beforehand with one of the dedicated modules. your choice, your consequences πŸ’…

the built-in nearest-neighbour resampling of raster data calculates the centre of each region cell, and takes the value of the raster cell in which that point falls. simple, clean.

⚠️ okay so this next bit is a real one: if the point falls exactly upon a grid line, the exact result will be determined by the direction of any rounding error. one consequence of this is that downsampling by a factor which is an even integer will always sample exactly on the boundary between cells, meaning that the result is ill-defined. so like… don't be surprised, bestie 😭

the following modules are available for reinterpolation of "filled" raster maps (continuous data) to a different resolution:

  • r.resample β€” uses the built-in resampling, so it should produce identical results as the on-the-fly resampling done via the raster import modules.
  • r.resamp.interp β€” resampling with nearest neighbor, bilinear, and bicubic method: method=nearest uses the same algorithm as r.resample, but not the same code, so it may not produce identical results in cases which are decided by the rounding of floating-point numbers. for r.resamp.interp method=bilinear and method=bicubic, the raster values are treated as samples at each raster cell's centre, defining a piecewise-continuous surface. the resulting raster values are obtained by sampling the surface at each region cell's centre. and because the algorithm only interpolates and doesn't extrapolate, a margin of 0.5 (for bilinear) or 1.5 (for bicubic) cells is lost from the extent of the original raster. any samples taken within this margin will be null. sad but true πŸ₯²
  • r.resamp.rst β€” Regularized Spline with Tension (RST) interpolation 2D. behaves similarly, i.e. it computes a surface assuming that the values are samples at each raster cell's centre, and samples the surface at each region cell's centre.
  • r.resamp.bspline β€” bicubic or bilinear spline interpolation with Tykhonov regularization.
  • r.resamp.stats β€” without -w, the value of each region cell is the chosen aggregate of the values from all of the raster cells whose centres fall within the bounds of the region cell. with -w, the samples are weighted according to the proportion of the raster cell which falls within the bounds of the region cell, so the result is normally unaffected by rounding error (a minuscule difference in the position of the boundary results in the addition or subtraction of a sample weighted by a minuscule factor; also, the min and max aggregates can't use weights, so -w has no effect for those).
  • r.fillnulls β€” for Regularized Spline with Tension (RST) interpolation 2D for hole filling (e.g., SRTM DEM). the hole-filler upper, we stan 🫢

furthermore, there are modules available for reinterpolation of "sparse" (scattered points or lines) maps:

  • Inverse distance weighted average (IDW) interpolation (r.surf.idw)
  • Interpolating from contour lines (r.contour)
  • Various vector modules for interpolation

for Lidar and similar data, r.in.pdal and r.in.xyz support loading and binning of ungridded x,y,z ASCII data into a new raster map. and the user may choose from a variety of statistical methods when creating that new raster map. build-your-own-adventure energy ✨

otherwise, for interpolation of scattered data, use the v.surf.* set of modules. iykyk 🌸

🧚 Raster MASKs 🧚

if a raster map named "MASK" exists, most GRASS raster modules will operate only on data falling inside the masked area, and treat any data falling outside of the mask as if its value were NULL. the mask is only applied when reading an existing GRASS raster map β€” for example when it's used in a module as an input map.

the mask is read as an integer map. if MASK is actually a floating-point map, the values will be converted to integers using the map's quantisation rules (this defaults to round-to-nearest, but can be changed with r.quant).

(see r.mask)

πŸ’œ Raster map statistics πŸ’œ

a couple of commands are available to calculate local statistics (r.neighbors), and global statistics (r.statistics, r.surf.area). profiles and transects can be generated (d.profile, r.profile, r.transect) as well as histograms (d.histogram) and polar diagrams (d.polar). univariate statistics (r.univar) and reports are also available (r.report, r.stats, r.volume).

and since r.univar may be slow for extended statistics, these can be calculated using r.stats.quantile. without a zones input raster, the r.quantile module will be significantly more efficient for calculating percentiles with large maps. for calculating univariate statistics from a raster map based on a vector polygon map and uploading those statistics to new attribute columns, see v.rast.stats. category or object oriented statistics can be computed with r.statistics. for floating-point cover map support for this, see the alternative r.stats.zonal. for quantile calculations with support for floating-point cover maps, see the alternative r.stats.quantile. so many options, all valid, all slaying πŸ’…

πŸ¦‹ Raster map algebra and aggregation πŸ¦‹

the r.mapcalc command provides raster map algebra methods. the r.resamp.stats command resamples raster map layers using various aggregation methods, and the r.statistics command aggregates one map based on a second map. r.resamp.interp resamples raster map layers using interpolation. math girlies rise up πŸŽ€

πŸ‘‘ Regression analysis πŸ‘‘

both linear (r.regression.line) and multiple regression (r.regression.multi) are supported. that's it, that's the whole section, short and sweet ✨

πŸ’€ Hydrologic modeling toolbox πŸ’€

Watershed modeling related modules are r.basins.fill, r.water.outlet, r.watershed, and r.terraflow.

Water flow related modules are r.carve, r.drain, r.fill.dir, r.fillnulls, r.flow, and r.topidx.

Flooding can be simulated with r.lake.

Hydrologic simulation models are available as r.sim.sediment, r.sim.water, and r.topmodel. the water girlies are eating good today 🌊


🌈 Raster format 🌈

in GRASS GIS, raster data can be stored as 2D or 3D grids. simple as that.

πŸ“ 2D raster maps πŸ“

2D rasters support three data types (for technical details, please refer to the Wiki article GRASS raster semantics):

  • 32bit signed integer (CELL),
  • single-precision floating-point (FCELL), and
  • double-precision floating-point (DCELL).

in most GRASS GIS resources, 2D raster maps are usually called "raster" maps. casual, iconic, no notes πŸ’–


to be continued, bestie… more raster lore incoming πŸ¦‹

πŸ’Ž 3D raster maps πŸ’Ž

okay so the 3D raster map type is usually called "3D raster", but bestie, people call it so many things β€” "RASTER3D", "voxel", "volume", "GRID3D" or "3d cell" are all out there in the wild and all mean the same thing. iykyk.

And here's the tea: 3D rasters only support single- and double-precision floating-point. The single-precision data type is most often called "float", and the double-precision one "double". That's it, that's the whole menu. πŸ’…


🫧 No-data management and data portability 🫧

GRASS GIS distinguishes NULL and zero β€” they are NOT the same thing, do not come for me on this. When you're working with NULL data, the important thing to know is that operations on NULL cells lead to NULL cells. So like… it spreads. NULL in, NULL out. πŸ™ˆ

The GRASS GIS raster format is architecture independent and portable between 32bit and 64bit machines. She travels well, no cap. ✈️


πŸ—œοΈ Raster compression πŸ—œοΈ

All GRASS GIS raster map types are by default ZSTD compressed if available, otherwise ZLIB compressed. Through the environment variable GRASS_COMPRESSOR the compression method can be set to RLE, ZLIB, LZ4, BZIP2, or ZSTD. Pick your fighter. πŸŽ€

Important: the NULL file compression can be turned off with export GRASS_COMPRESS_NULLS=0. Raster maps with NULL file compression can only be opened with GRASS GIS 7.2.0 or later. NULL file compression for a particular raster map can be managed with r.null -z. πŸ‘‘

Integer (CELL type) raster maps can be compressed with RLE if the environment variable GRASS_COMPRESSOR exists and is set to RLE. However, this is not recommended. Not me warning you twice. 😭

Floating point (FCELL, DCELL) raster maps never use RLE compression; they are either compressed with ZLIB, LZ4, BZIP2, ZSTD or are uncompressed.

πŸ¦‹ RLE πŸ¦‹

DEPRECATED β€” Run-Length Encoding, poor compression ratio but fast. It is kept for backwards compatibility to read raster maps created with GRASS 6. It is only used for raster maps of type CELL. FCELL and DCELL maps are never and have never been compressed with RLE. Like, never ever, fr fr.

🌸 ZLIB 🌸

ZLIB's deflate is the default compression method for all raster maps, if ZSTD is not available. GRASS GIS 8 uses by default 1 as ZLIB compression level which is the best compromise between speed and compression ratio, also when compared to other available compression methods. Valid levels are in the range [1, 9] and can be set with the environment variable GRASS_ZLIB_LEVEL. She's the reliable friend who always shows up. 🫢

⭐ LZ4 ⭐

LZ4 is a very fast compression method, about as fast as no compression. Decompression is also very fast. The compression ratio is generally higher than for RLE but worse than for ZLIB. LZ4 is recommended if disk space is not a limiting factor. Speed queen energy. πŸ’¨

πŸ“ BZIP2 πŸ“

BZIP2 can provide compression ratios much higher than the other methods, but only for large raster maps (> 10000 columns). For large raster maps, disk space consumption can be reduced by 30 - 50% when using BZIP2 instead of ZLIB's deflate. BZIP2 is the slowest compression and decompression method. However, if reading from / writing to a storage device is the limiting factor, BZIP2 compression can speed up raster map processing. Be aware that for smaller raster maps, BZIP2 compression ratio can be worse than other compression methods. Big data? slay. Small data? she's struggling, bestie. 😭

🌈 ZSTD 🌈

ZSTD (Zstandard) provides compression ratios higher than ZLIB but lower than BZIP2 (for large data). ZSTD compresses up to 4x faster than ZLIB, and usually decompresses 6x faster than ZLIB. ZSTD is the default compression method if available. the moment she walked in… iconic πŸ‘‘

In the internal cellhd file, the value for "compressed" is 1 for RLE, 2 for ZLIB, 3 for LZ4, 4 for BZIP2, and 5 for ZSTD. The lore. πŸ“–

Obviously, decompression is controlled by the raster map's compression, not the environment variable. The file decides, not you. periodt. πŸ’…


πŸ”₯ See also πŸ”₯

  • Introduction into 3D raster data (voxel) processing
  • Introduction into vector data processing
  • Introduction into image processing
  • Introduction into temporal data processing
  • Database management
  • Projections and spatial transformations
  • Graphical User Interface

🧚 SOURCE CODE 🧚

Available at: Raster data processing in GRASS GIS source code (history)

Accessed: Friday Nov 21 14:02:57 2025

Main index | Raster index | Topics index | Keywords index | Graphical index | Full index

Β© 2003-2025 GRASS Development Team, GRASS GIS 8.4.2 Reference Manual


and that's the whole page, bestie!! πŸ’– this whole thing is from GRASS 8.4.2, and it's the rasterintro(1) manual page, accessed that one very specific Friday. go forth and compress responsibly, my love πŸ¦‹βœ¨

πŸ“¦ where this page comes from