r.fill.stats(1)
πΈ r.fill.stats(1) πΈ
okay so you opened the GRASS GIS User's Manual page for r.fill.stats and honestly? bestie, you're about to fill some gaps and it's gonna be gorgeous π
π NAME π
r.fill.stats β rapidly fills 'no data' cells (NULLs) of a raster map with interpolated values (IDW). yes literally just gap-filling but make it fast β¨
π·οΈ KEYWORDS π·οΈ
raster, surface, interpolation, IDW, no-data filling π
π SYNOPSIS π
r.fill.stats
r.fill.stats --help
r.fill.stats [-mkwus] input=name output=name [uncertainty=name]
distance=value mode=name [minimum=value] [maximum=value] power=value
cells=value [--overwrite] [--help] [--verbose] [--quiet] [--ui]
π© Flags π©
-mβ readdistanceas map units, not as a number of cells πΊοΈ-kβ keep (preserve) the original cell values. heads up tho: by default the original values get smoothed, so this flag is you saying "no thanks, leave my babies alone" π-wβ just print the spatial weights matrix, that's it, that's the whole job π-uβ just print the estimated memory usage-sβ single precision floating point output--overwriteβ let output files overwrite files that already exist--helpβ print usage summary--verboseβ verbose module output (she's chatty π¬)--quietβ quiet module output (she's not)--uiβ force launching the GUI dialog
π§Έ Parameters π§Έ
input=name[required] β raster map with data gaps to filloutput=name[required] β name of the result output mapuncertainty=nameβ name of the uncertainty output mapdistance=value[required] β distance threshold (default: in cells) for interpolation. Default:3mode=name[required] β statistic for interpolated cell values. Options:wmean,mean,median,mode. Default:wmeanminimum=valueβ minimum input data value to include in interpolationmaximum=valueβ maximum input data value to include in interpolationpower=value[required] β power coefficient for IDW interpolation. Default:2.0cells=value[required] β minimum number of data cells within the search radius. Default:8
π DESCRIPTION π
okay so r.fill.stats is a module for fast gap filling and interpolation (with smoothing) of dense raster data. she's built different fr fr.
the r.fill.stats module can rapidly fill small data gaps in large and high-resolution raster maps. her primary purpose is improving high-resolution, rasterized sensor data (like Lidar data π). as a rule of thumb, there should be at least as many data cells as there are "no data" (NULL) cells in the input raster map. several interpolation modes are available. by default, all values of the input raster map get replaced with locally interpolated values in the output raster map. that's the equivalent of running a low-pass smoothing filter on the interpolated data, and honestly it's often exactly what you want, because high-resolution sensor data is noisy like that π. with dense data and small gaps, this should only give you slight deviations from the original data and produce smooth output. alternatively, setting the -k flag disables the low-pass filter and preserves the original cell values. periodt.
available gap filling modes:
- spatially weighted mean (default) β¨
- simple mean
- simple median
- simple mode
the spatially weighted mean is equivalent to an Inverse Distance Weighting (IDW; see also r.surf.idw) interpolation. the simple mean is equivalent to a simple low-pass filter. median and mode replacements can also be achieved using r.neighbors.
ngl, note that r.fill.stats is highly optimized for fast processing of large raster datasets with a small interpolation distance threshold (i.e. closing small gaps). as a trade-off for speed and a small memory footprint, some spatial accuracy is lost β because the distance threshold gets rounded to the closest approximation in input raster cells, and because of the matrix of precomputed weights at cell resolution (more on that further down π). also note that processing time will increase exponentially with higher distance settings. cells outside the distance threshold will not be interpolated, which preserves the edges of the original data extent. π«Ά
this module is not well suited for interpolating sparse input data and closing large gaps. for that kinda thing, more appropriate methods exist, like v.surf.bspline, v.surf.idw or v.surf.rst.
applications where the properties of r.fill.stats are advantageous include processing high resolution, close range scanning and remote sensing datasets. such datasets commonly feature densely spaced measurements that have some gaps after rasterization, because of blind spots, instrument failures, and misalignments between the GIS' raster cell grids and the original measurement locations. in these cases, r.fill.stats should typically be run using the "weighted mean" (default) method and with a small distance setting (the default is a search radius of just three cells). π
the images below show a gradiometer dataset with gaps and its interpolated equivalent, produced using the spatially weighted mean operator (mode="wmean"). πΈ
in addition, r.fill.stats can be useful for raster map generalization. often this involves removing small clumps of categorized cells and then filling the resulting data gaps without "inventing" any new values. in such cases, the "mode" or "median" interpolators should be used.
π οΈ Usage π οΈ
the most critical user-provided settings are the interpolation/gap filling method (mode) and the maximum distance up to which r.fill.stats will scan for cells with values (distance). the distance can be expressed as a number of cells (default) or in the current coordinate reference system's units (if the -m flag is given). the latter are typically meters, but can be any other units of a planar coordinate system. π
note that proper handling of geodetic coordinates (lat/lon) and distances is currently not implemented. for lat/lon data, thedistanceshould therefore be specified in cells, and usage ofr.fill.statsshould be restricted to small areas to avoid large inaccuracies that may arise from the different extents of cells along the latitudinal and longitudinal axes. β οΈ
distances specified in map units (-m flag) will be approximated as accurately as the current region's cell resolution settings allow. the program will warn if the distance cannot be expressed as whole cells at the current region's resolution. in such a case, the number of cells in the search window will be rounded up. due to the rounding effect introduced by using cells as spatial units, the actual maximum distance considered by the interpolation may be up to half a cell diagonal larger than the one specified by the user.
the interpolator type "wmean" uses a precomputed matrix of spatial weights to speed up computation. this matrix can be examined (printed to the screen) before running the interpolation, by setting the -w flag. in mode "wmean", the power option has the usual meaning in IDW: higher values mean that cell values in the neighborhood lose their influence on the cell to be interpolated more rapidly as distance from the latter increases. another way of explaining this effect: larger power settings result in more localized interpolation, smaller ones in more globalized interpolation. the default setting is power=2.0. π«
the interpolators "mean", "median" and "mode" are calculated from all cell values within the search radius. no spatial weighting is applied for these methods. the "mode" of the input data may not always be unique. in such a case, the mode will be the smallest value with the highest frequency. π
often, input data will contain spurious extreme measurements (spikes, outliers, noise) caused by the limits of device sensitivity, hardware defects, environmental influences, etc. if the normal, valid range of input data is known beforehand, then the minimum and maximum options can be used to exclude those input cells that have values below or above that range, respectively. this will prevent the influence of spikes and outliers from spreading through the interpolation. π‘οΈ
unless the -k (keep) flag is given, data cells of the input map will be replaced with interpolated values instead of preserving them in the output. in modes "wmean" and "mean", this results in a smoothing effect that includes the original data (see below)!
besides the result of the interpolation/gap filling, a second output map can be specified via the uncertainty option. the cell values in this map represent a simple measure of how much uncertainty was involved in interpolating each cell value of the primary output map, with "0" being the lowest and "1" being the theoretic highest uncertainty. uncertainty is measured by summing up all cells in the neighborhood (defined by the search radius distance) that contain a value in the input map, multiplied by their weights, and dividing the result by the sum of all weights in the neighborhood. for mode=wmean, this means that interpolated output cells computed from many nearby input cells have very low uncertainty and vice versa. for all other modes, all weights in the neighborhood are constant "1" and the uncertainty measure is a simple measure of how many input data cells were present in the search window. π
π§΄ Smoothing π§΄
the r.fill.stats module uses the interpolated values to adjust the original values and create a smooth surface, which is akin to running a low-pass filter on the data. since most high-resolution sensor data is noisy, this is normally a desired effect and results in output that's more suitable for deriving secondary products, such as slope, aspect and curvature maps. larger settings for the search radius (distance) will result in a stronger smoothing. in practice, some experimentation with different settings for distance and power might be required to achieve good results. in some cases (e.g. when dealing with low-noise or classified data), it might be desirable to turn off data smoothing by setting the -k (keep) flag. this will ensure that the original cell data is copied through to the result map without alteration. π§Ό
Effect of smoothing the original data: the top row shows a gap-filled surface computed from a rasterized Lidar point cloud (using mode=wmean and power=2), and the derived slope, aspect, and profile curvature maps. the smoothing effect is clearly visible. the bottom row shows the effect of setting the -k flag: preserving the original cell values in the interpolated output produces an unsmoothed, noisy surface, and likewise noisy derivative maps. the effect can be seen in the illustration above: slope, aspect, and profile curvature are computed using the r.slope.aspect module, which uses a window (kernel) for computations that considers only the immediate neighborhood of each cell. when performed on noisy data, such local operations result in equally noisy derivatives if the original data is preserved (by setting the -k flag) and no smoothing is performed. ππ
okay bestie that's just the first half β there's MORE coming, don't go anywhere π
ok bestie real talk β that last bit about noisy data? here's the tea: you can dodge the whole noisy-data situation by reaching for modules that aren't locked into tiny minimal kernel sizes. like,aspectand other morphometric parameters can be computed with ther.param.scalemodule, which does its thing with variable-size cell neighborhoods. slay π
β¨ Spatial weighting scheme β¨
okay so this is THE thing you have to get if you want your gap filling to actually eat. the secret sauce in mode "wmean" is the spatial weighting scheme. the weights are precomputed and assigned per cell inside the search window that's centered on the exact location where you're interpolating/gap filling β and that window covers all cells within the distance you specified. π―
here's the precomputed weights matrix for a search distance of four cells from the center cell, look at her:
000.00 000.01 000.04 000.07 000.09 000.07 000.04 000.01 000.00
000.01 000.06 000.13 000.19 000.22 000.19 000.13 000.06 000.01
000.04 000.13 000.25 000.37 000.42 000.37 000.25 000.13 000.04
000.07 000.19 000.37 000.56 000.68 000.56 000.37 000.19 000.07
000.09 000.22 000.42 000.68 001.00 000.68 000.42 000.22 000.09
000.07 000.19 000.37 000.56 000.68 000.56 000.37 000.19 000.07
000.04 000.13 000.25 000.37 000.42 000.37 000.25 000.13 000.04
000.01 000.06 000.13 000.19 000.22 000.19 000.13 000.06 000.01
000.00 000.01 000.04 000.07 000.09 000.07 000.04 000.01 000.00
lowkey notice how fast those weights drop off in such a tiny window for the default setting of power=2. it's giving steep. π
now, if you hand over the distance in map units (that's flag -m), the search window can be modeled way more accurately as a circle. here's the precomputed weights for a distance in map units that's approximately equivalent to four cells from the center cell:
...... ...... ...... 000.00 000.00 000.00 ...... ...... ......
...... 000.00 000.02 000.06 000.09 000.06 000.02 000.00 ......
...... 000.02 000.11 000.22 000.28 000.22 000.11 000.02 ......
000.00 000.07 000.22 000.44 000.58 000.44 000.22 000.07 000.00
000.00 000.09 000.28 000.58 001.00 000.58 000.28 000.09 000.00
000.00 000.07 000.22 000.44 000.58 000.44 000.22 000.07 000.00
...... 000.02 000.11 000.22 000.28 000.22 000.11 000.02 ......
...... 000.00 000.02 000.06 000.09 000.06 000.02 000.00 ......
...... ...... ...... 000.00 000.00 000.00 ...... ...... ......
and like, when you're working with a small search radius, the cells also have to be set to a small value. otherwise there might not be enough cells with data inside that radius to support interpolation, and then it's just vibes and no numbers. π
πΈ NOTES πΈ
- the straight-line metric used for converting distances in map units into cell numbers is only adequate for planar coordinate systems. fr fr, using this module with lat/lon input data will likely give you inaccurate results β especially when you're interpolating over big geographical areas. π«
- if you set the distance to a relatively large value, processing time will quickly approach β and eventually exceed β that of point-based interpolation modules like
v.surf.rst. not me waiting forever π - this module can handle cells with different X and Y resolutions. but bestie, heads up: the weight matrix will be skewed in those cases, with higher weights showing up close to the center and along the axis with the higher resolution. why? because weights on the lower-resolution axis are less accurately calculated. the skewing gets stronger the bigger the difference between X and Y axis resolution is, and the larger your
"power"setting is. and honestly? that property of the weights matrix directly reflects the higher information density along the higher resolution axis. iconic behavior honestly β¨ - note on printing the weights matrix (with the
-wflag): the matrix cannot be printed if it is too large. that's it, that's the rule. π - the memory estimate that the
-uflag hands you is a lower limit on the amount of RAM you're actually gonna need. plan accordingly, queen π - if the
-sflag is set, floating point type output gets saved as a"single precision"raster map β that's ~50% disk space saved compared to the default"double precision"output. your hard drive will thank you π«Ά
π EXAMPLES π
π Gap-filling of a dataset using spatially weighted mean (IDW) π
gap-fill a dataset using spatially weighted mean (IDW) with a maximum search radius of 3.0 map units, and also produce an uncertainty estimation map while you're at it:
r.fill.stats input=measurements output=result dist=3.0 -m mode=wmean uncertainty=uncert_map
run a fast low-pass filter (replacement all cells with mean value of neighboring cells) on the input map:
r.fill.stats input=measurements output=result dist=10 mode=mean
fill data gaps in a categorized raster map, but preserve the existing data:
r.fill.stats input=categories output=result dist=100 -m mode=mode -k
π¦ Lidar point cloud example π¦
first, inspect the point density and figure out the extent of the point cloud using the r.in.pdal module:
r.in.pdal -e input=points.las output=density method=n resolution=5 class_filter=2
based on the result, set the computational region extent and desired resolution:
g.region -pa raster=density res=1
import the point cloud as raster using binning:
r.in.pdal input=points.las output=ground_raw method=mean class_filter=2
check that there are more non-NULL cells than NULL ("no data") cells:
r.univar map=ground_raw
total null and non-null cells: 2340900
total null cells: 639184
...
fill in the NULL cells using the default 3-cell search radius:
r.fill.stats input=ground output=ground_filled uncertainty=uncertainty distance=3 mode=wmean power=2.0 cells=8
Binning of Lidar and resulting ground surface with filled gaps. Note the remaining NULL cells (white) in the resulting ground surface. These are areas with a lack of cells with values in close proximity. β
π Outlier removal and gap-filling of SRTM elevation data π
in this example, the SRTM elevation map in the North Carolina sample dataset gets filtered for outlier elevation values, and then the missing pixels get re-interpolated so we end up with a complete elevation map:
g.region raster=elev_srtm_30m -p
d.mon wx0
d.histogram elev_srtm_30m
# remove SRTM outliers, i.e. SRTM below 50m (esp. lakes), leading to no data areas
r.mapcalc "elev_srtm_30m_filt = if(elev_srtm_30m < 50.0, null(), elev_srtm_30m)"
d.histogram elev_srtm_30m_filt
d.rast elev_srtm_30m_filt
# using the IDW method to fill these holes in DEM without low-pass filter
# increase distance to gap-fill larger holes
r.fill.stats -k input=elev_srtm_30m_filt output=elev_srtm_30m_idw distance=100
d.histogram elev_srtm_30m_idw
d.rast elev_srtm_30m_idw
r.mapcalc "diff_orig_idw = elev_srtm_30m - elev_srtm_30m_idw"
r.colors diff_orig_idw color=differences
r.univar -e diff_orig_idw
d.erase
d.rast diff_orig_idw
d.legend diff_orig_idw
π SEE ALSO π
r.fillnulls,r.neighbors,r.surf.idw,v.surf.bspline,v.surf.idw,v.surf.rst,v.fill.holes
Inverse Distance Weighting in Wikipedia π
π AUTHOR π
Benjamin Ducke
β SOURCE CODE β
Available at: r.fill.stats source code (history)
Accessed: Saturday Jan 17 05:40:46 2026
Main index | Raster index | Topics index | Keywords index | Graphical index | Full index
and that's a wrap bestie π«Ά this page is from the GRASS 8.4.2 reference manual, page r.fill.stats(1), Β© 2003-2025 GRASS Development Team. go fill those gaps, you absolute legend π
β¨
π¦ where this page comes from
- fedora 44: grass 8.4.2-4.fc44 Β· GPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms