Smooth out the jagged or sharp corners of spatial lines or polygons to make them appear more aesthetically pleasing and natural.
smooth(x, method = c("chaikin", "ksmooth", "spline", "densify"), ...)
spatial features; lines or polygons from either the sf
, sp
, or
terra
packages.
character; specifies the type of smoothing method to use.
Possible methods are: "chaikin"
, "ksmooth"
, "spline"
, and
"densify"
. Each method has one or more parameters specifying the amount
of smoothing to perform. See Details for descriptions.
additional arguments specifying the amount of smoothing, passed on to the specific smoothing function, see Details below.
A smoothed polygon or line in the same format as the input data.
Specifying a method calls one of the following underlying smoothing functions. Each smoothing method has one or more parameters that specify the extent of smoothing. Note that for multiple features, or multipart features, these parameters apply to each individual, singlepart feature.
smooth_chaikin()
: Chaikin's corner cutting algorithm smooths a curve by
iteratively replacing every point by two new points: one 1/4 of the way to
the next point and one 1/4 of the way to the previous point. Smoothing
parameters:
refinements
: number of corner cutting iterations to apply.
smooth_ksmooth()
: kernel smoothing via the stats::ksmooth()
function.
This method first calls smooth_densify()
to densify the feature, then
applies Gaussian kernel regression to smooth the resulting points.
Smoothing parameters:
smoothness
: a positive number controlling the smoothness and level of
generalization. At the default value of 1, the bandwidth is chosen as
the mean distance between adjacent vertices. Values greater than 1
increase the bandwidth, yielding more highly smoothed and generalized
features, and values less than 1 decrease the bandwidth, yielding less
smoothed and generalized features.
bandwidth
: the bandwidth of the Guassian kernel. If this argument is
supplied, then smoothness
is ignored and an optimal bandwidth is not
estimated.
n
: number of times to split each line segment in the densification
step. Ignored if max_distance
is specified.
max_distance
: the maximum distance between vertices in the resulting
features for the densification step. This is the Euclidean distance and
not the great circle distance.
smooth_spline()
: spline interpolation via the stats::spline()
function. This method interpolates between existing vertices and can be
used when the resulting smoothed feature should pass through the vertices
of the input feature. Smoothing parameters:
vertex_factor
: the proportional increase in the number of vertices in
the smooth feature. For example, if the original feature has 100
vertices, a value of 2.5 will yield a new, smoothed feature with 250
vertices. Ignored if n
is specified.
n
: number of vertices in each smoothed feature.
smooth_densify()
: densification of vertices for lines and polygons.
This is not a true smoothing algorithm, rather new vertices are added to
each line segment via linear interpolation. Densification parameters:
n
: number of times to split each line segment. Ignored if
max_distance
is specified.
max_distance
: the maximum distance between vertices in the resulting
feature. This is the Euclidean distance and not the great circle
distance.
See specific smoothing function help pages for references.
library(sf)
# compare different smoothing methods
# polygons
par(mar = c(0, 0, 0, 0), oma = c(4, 0, 0, 0), mfrow = c(3, 3))
p_smooth_chaikin <- smooth(jagged_polygons, method = "chaikin")
p_smooth_ksmooth <- smooth(jagged_polygons, method = "ksmooth")
p_smooth_spline <- smooth(jagged_polygons, method = "spline")
for (i in 1:nrow(jagged_polygons)) {
plot(st_geometry(p_smooth_spline[i, ]), col = NA, border = NA)
plot(st_geometry(jagged_polygons[i, ]), col = "grey40", border = NA, add = TRUE)
plot(st_geometry(p_smooth_chaikin[i, ]), col = NA, border = "#E41A1C", lwd = 2, add = TRUE)
plot(st_geometry(p_smooth_ksmooth[i, ]), col = NA, border = "#4DAF4A", lwd = 2, add = TRUE)
plot(st_geometry(p_smooth_spline[i, ]), col = NA, border = "#377EB8", lwd = 2, add = TRUE)
}
par(fig = c(0, 1, 0, 1), oma = c(0, 0, 0, 0), new = TRUE)
plot(0, 0, type = "n", bty = "n", xaxt = "n", yaxt = "n", axes = FALSE)
legend("bottom", legend = c("chaikin", "ksmooth", "spline"),
col = c("#E41A1C", "#4DAF4A", "#377EB8"),
lwd = 2, cex = 2, box.lwd = 0, inset = 0, horiz = TRUE)
# lines
par(mar = c(0, 0, 0, 0), oma = c(4, 0, 0, 0), mfrow = c(3, 3))
l_smooth_chaikin <- smooth(jagged_lines, method = "chaikin")
l_smooth_ksmooth <- smooth(jagged_lines, method = "ksmooth")
l_smooth_spline <- smooth(jagged_lines, method = "spline")
for (i in 1:nrow(jagged_lines)) {
plot(st_geometry(l_smooth_spline[i, ]), col = NA)
plot(st_geometry(jagged_lines[i, ]), col = "grey20", lwd = 3, add = TRUE)
plot(st_geometry(l_smooth_chaikin[i, ]), col = "#E41A1C", lwd = 2, lty = 2, add = TRUE)
plot(st_geometry(l_smooth_ksmooth[i, ]), col = "#4DAF4A", lwd = 2, lty = 2, add = TRUE)
plot(st_geometry(l_smooth_spline[i, ]), col = "#377EB8", lwd = 2, lty = 2, add = TRUE)
}
par(fig = c(0, 1, 0, 1), oma = c(0, 0, 0, 0), new = TRUE)
plot(0, 0, type = "n", bty = "n", xaxt = "n", yaxt = "n", axes = FALSE)
legend("bottom", legend = c("chaikin", "smooth", "spline"),
col = c("#E41A1C", "#4DAF4A", "#377EB8"),
lwd = 2, cex = 2, box.lwd = 0, inset = 0, horiz = TRUE)