v.surf.bspline(1grass)

✨ NAME ✨

v.surf.bspline β€” it does bicubic or bilinear spline interpolation, with Tykhonov regularization. That's the whole vibe. Go off. πŸ’…

It's part of GRASS, so that's the (1grass) energy right there in the corner. Bestie manual, we're in it.


πŸŽ€ KEYWORDS πŸŽ€

vector, surface, interpolation, LIDAR

Yes, LIDAR. We love a point cloud.


🌸 SYNOPSIS 🌸

v.surf.bspline
v.surf.bspline --help
v.surf.bspline [-ce] input=name  [layer=string]   [column=name]
[sparse_input=name]   [output=name]   [raster_output=name]   [mask=name]
[ew_step=float]   [ns_step=float]   [method=string]   [lambda_i=float]
[solver=name]   [maxit=integer]   [error=float]   [memory=memory in MB]
[--overwrite]  [--help]  [--verbose]  [--quiet]  [--ui]

🚩 Flags

  • -c β€” it finds the best Tykhonov regularizing parameter using a "leave-one-out" cross validation method. It's giving science. πŸ‘‘
  • -e β€” estimates point density and distance. Specifically: it estimates point density and distance in map units for the input vector points within the current region extents, and then quits. Like, it just peeks and leaves. πŸ’¨
  • --overwrite β€” lets output files overwrite existing files. Use with intent, bestie. ⚠️
  • --help β€” prints the usage summary. Your safe space.
  • --verbose β€” verbose module output. It talks more. πŸ—£οΈ
  • --quiet β€” quiet module output. It talks less. 🀫
  • --ui β€” forces launching the GUI dialog. For when you want buttons, not typing.

🧸 Parameters

  • input=name [required] β€” name of input vector point map. Or a data source for direct OGR access. You literally cannot skip this one.
  • layer=string β€” layer number or name. Vector features can have category values in different layers, and this number determines which layer to use. When used with direct OGR access, this here is the layer name. Default: 1.
  • column=name β€” name of the attribute column with the values to be used for approximation. If it's not given and input is a 3D vector map, then z-coordinates are used instead. No column? z it is. 🎯
  • sparse_input=name β€” name of input vector map with sparse points. Or a data source for direct OGR access.
  • output=name β€” name for output vector map.
  • raster_output=name β€” name for output raster map.
  • mask=name β€” raster map to use for masking (this applies to raster output only). Only cells that are not NULL and not zero get interpolated. Everything else? Not invited to the party. 🚫
  • ew_step=float β€” length of each spline step in the east-west direction. Default: 4 * east-west resolution.
  • ns_step=float β€” length of each spline step in the north-south direction. Default: 4 * north-south resolution.
  • method=string β€” spline interpolation algorithm. Options: bilinear, bicubic. Default: bilinear. And to spell it out: bilinear is bilinear interpolation, bicubic is bicubic interpolation. Pick your fighter. πŸ₯Š
  • lambda_i=float β€” Tykhonov regularization parameter (affects smoothing). Default: 0.01.
  • solver=name β€” the type of solver which should solve the symmetric linear equation system. Options: cholesky, cg. Default: cholesky.
  • maxit=integer β€” maximum number of iteration used to solve the linear equation system. Default: 10000.
  • error=float β€” error break criteria for iterative solver. Default: 0.000001.
  • memory=memory in MB β€” maximum memory to be used (in MB). Also the cache size for raster rows. Default: 300.

πŸ’– DESCRIPTION πŸ’–

v.surf.bspline performs a bilinear/bicubic spline interpolation with Tykhonov regularization. The input is a 2D or 3D vector point layer. The values you interpolate can be the z values of 3D points, or the values in a user-specified attribute column in a 2D or 3D vector layer. The output can be a raster (raster_output) or a vector (output) layer.

And optionally β€” plot twist β€” a "sparse point" vector layer can be input, which indicates the location of the output vector points. ✨


πŸ“ NOTES πŸ“

Okay so, theory time. Stay with me, it's actually cute.

From a theoretical perspective, the interpolating procedure takes place in two parts. First, an estimate of the linear coefficients of a spline function, which is derived from the observation points using a least squares regression. Second, the computation of the interpolated surface or interpolated vector points.

As used here, the splines are 2D piece-wise non-zero polynomial functions calculated within a limited, 2D area. The length, in mapping units, of each spline step is defined by ew_step for the east-west direction and ns_step for the north-south direction. For optimal performance, the length of spline step should be no less than the distance between observation points.

Each vector point observation is modeled as a linear function of the non-zero splines in the area around the observation. The least squares regression predicts the coefficients of these linear functions. Regularization avoids the need to have one observation and one coefficient for each spline (in order to avoid instability). 🫢

With regularly distributed data points, a spline step corresponding to the maximum distance between two points in both the east and north directions is sufficient. However, data points are often not regularly distributed and require statistical regularization or estimation. In such cases, v.surf.bspline will attempt to minimize the gradient of bilinear splines or the curvature of bicubic splines in areas lacking point observations.

As a general rule, the spline step length should be greater than the mean distance between observation points (twice the distance between points is a good starting point). Separate east-west and north-south spline step length arguments allows the user to account for some degree of anisotropy in the distribution of observation points.

Careful, bestie: short spline step lengths, especially spline step lengths that are less than the distance between observation points, can greatly increase the processing time. We do not love that for us. 😭

The maximum number of splines for each direction at each time is fixed, regardless of the spline step length. As the total number of splines increases (i.e., with small spline step lengths), the region is automatically split into subregions for interpolation. Each subregion can contain no more than 150x150 splines. To avoid subregion boundary problems, subregions are created to partially overlap each other. A weighted mean of observations, based on point locations, is calculated within each subregion.

The Tykhonov regularization parameter, lambda_i, acts to smooth the interpolation. With a small lambda_i, the interpolated surface closely follows observation points; a larger value will produce a smoother interpolation. Tiny lambda = clingy surface, big lambda = chill surface. That's the whole arc. 🌈

The input can be a 2D or 3D point vector layer. If input is 3D and column is not given, then z-coordinates are used for interpolation. Parameter column is required when input is a 2D vector layer. No cap.

v.surf.bspline can produce raster (raster_output) OR vector output but NOT simultaneously. It's giving monogamy. Also note that topology is not built for the output point vector layer. If required, the topology can be built using v.build.

If output is a point vector layer and sparse is not specified, the output vector layer will contain points at the same locations as observation points in the input layer β€” but the values of the output points will be interpolated values. If a sparse point vector layer is specified, the output vector layer will contain points at the same locations as the sparse vector layer points. The values will be those of the interpolated raster surface at those points. πŸ’«

A cross validation "leave-one-out" analysis is available to help to determine the optimal lambda_i value that produces an interpolation that best fits the original observation data. The more points used for cross-validation, the longer the time needed for computation. Empirical testing indicates a threshold of a maximum of 100 points is recommended.

Heads up: cross validation can run very slowly if more than 100 observations are used. Don't do it to yourself. πŸ™ˆ

The cross-validation output reports mean and rms of the residuals from the true point value and the estimated from the interpolation for a fixed series of lambda_i values. No vector nor raster output will be created when cross-validation is selected. F in the chat for your empty output folder. πŸ’€


πŸ¦‹ EXAMPLES πŸ¦‹

Basic interpolation

v.surf.bspline input=point_vector output=interpolate_surface method=bicubic

A bicubic spline interpolation will be done and a point vector layer with estimated (i.e., interpolated) values will be created. Slay. ✨

Basic interpolation and raster output with a longer spline step

v.surf.bspline input=point_vector raster=interpolate_surface ew_step=25 ns_step=25

A bilinear spline interpolation will be done with a spline step length of 25 map units. An interpolated raster layer will be created at the current region resolution.

Estimation of lambda_i parameter with a cross validation process

v.surf.bspline -c input=point_vector

Look at her go, finding her own parameters. Main character energy. πŸ‘‘

Estimation on sparse points

v.surf.bspline input=point_vector sparse=sparse_points output=interpolate_surface

An output layer of vector points will be created, corresponding to the sparse vector layer, with interpolated values.

Using attribute values instead z-coordinates

v.surf.bspline input=point_vector raster=interpolate_surface layer=1 \
  column=attrib_column

The interpolation will be done using the values in attrib_column, in the table associated with layer 1. (Yes, that backslash means it wraps to the next line β€” bash said "one line, two lines, whatever, it's still one command.") 🧚

North Carolina dataset example using z-coordinates for interpolation

g.region region=rural_1m res=2 -p
v.surf.bspline input=elev_lid792_bepts raster=elev_lid792_rast \
  ew_step=5 ns_step=5 method=bicubic lambda_i=0.1

🚨 KNOWN ISSUES 🚨

Okay this one's for real, listen up.

In order to avoid RAM memory problems, an auxiliary table is needed for recording some intermediate calculations. This requires the GROUP BY SQL function is used. This function is not supported by the DBF driver. For this reason, vector output (output) is not permitted with the DBF driver.

There are no problems with the raster map output from the DBF driver. So raster? Fine. Vector with DBF? Absolutely not. πŸ™…β™€οΈ


πŸ“š REFERENCES πŸ“š

  • Brovelli M. A., Cannata M., and Longoni U.M., 2004, LIDAR Data Filtering and DTM Interpolation Within GRASS, Transactions in GIS, April 2004, vol. 8, iss. 2, pp. 155-174(20), Blackwell Publishing Ltd
  • Brovelli M. A. and Cannata M., 2004, Digital Terrain model reconstruction in urban areas from airborne laser scanning data: the method and an example for Pavia (Northern Italy). Computers and Geosciences 30, pp.325-331
  • Brovelli M. A e Longoni U.M., 2003, Software per il filtraggio di dati LIDAR, Rivista dell'Agenzia del Territorio, n. 3-2003, pp. 11-22 (ISSN 1593-2192)
  • Antolin R. and Brovelli M.A., 2007, LiDAR data Filtering with GRASS GIS for the Determination of Digital Terrain Models. Proceedings of Jornadas de SIG Libre, Girona, EspaΓ±a. CD ISBN: 978-84-690-3886-9

πŸ‘€ SEE ALSO πŸ‘€

v.surf.idw, v.surf.rst

Overview: Interpolation and Resampling in GRASS


πŸ’œ AUTHORS πŸ’œ

  • Original version (s.bspline.reg) in GRASS 5.4: Maria Antonia Brovelli, Massimiliano Cannata, Ulisse Longoni, Mirko Reguzzoni
  • Update for GRASS 6 and improvements: Roberto Antolin

✨ SOURCE CODE ✨

The whole thing is out there, bestie, open and free:

  • Available at: v.surf.bspline source code (history)

Last time it got a glow-up: Friday Apr 17 01:04:26 2026, in commit 32a143358df26b2e518b03c7e0d79541e8d1e5b1 πŸ’…


Wanna go down a rabbit hole? There's a whole lil hub of index pages waiting for you:

  • Main index
  • Vector index
  • Topics index
  • Keywords index
  • Graphical index
  • Full index

Β© 2003-2026 GRASS Development Team, GRASS 8.5.0 Reference Manual β€” that's the copyright tea, respect the elders 🫢

And that's the whole page, you ate that fr fr πŸ‘‘ This was v.surf.bspline from the GRASS 8.5.0 manual, dated Friday Apr 17 01:04:26 2026, and the commit that last touched it was 32a143358df26b2e518b03c7e0d79541e8d1e5b1. Go smooth some splines, bestie πŸ’–βœ¨

πŸ“¦ where this page comes from