I want to buffer a spatial polygon P of area A so that the buffered feature P_buffered attains a defined area A_buffered. Function sf::st_buffer
grows a feature by distance d (from edge) but not by area.
So far, I tried:
The accuracy of (1) varies with the feature's shape while (2) is too slow (at least my implementation of it)
I'd be very grateful for hints towards some package with a corresponding function (pseudo::buffer_area()
) or codewise solution I seem to be overlooking.
Re. accessing other GIS executables from R, please note that the code has to run on a machine where only the availability of R packages can be taken as granted.
example data: dput
dump of an example polygon class sfc
for use with {sf}: https://gist.github.com/1O/bc3798468b48f19ab2533f16c99c2268
I still suggest a while loop (your second approach)... perhals someone can tweak the growth/decline aloritm...
library(sf)
points = matrix(c(0,0,20,0,10,10,0,10,0,0),ncol=2, byrow=TRUE)
pts = list(points)
pl1 = st_polygon(pts)
# x = polygon
# y = desired buffer area
# z = allowed delte from area
# example y = 100, z = 0.01, the bufferarea aloowed is bewteen 99 and 101
buffer_distance <- function(x, y, z) {
buff_dist <- 1
buffer_area <- st_area(st_buffer(x, buff_dist)) - st_area(x)
while (!data.table::between(buffer_area,
y - z * y,
y + z * y)) {
if (buffer_area > y) {
buff_dist <- buff_dist * (1 - y / st_area(st_buffer(x, buff_dist) ))
} else {
buff_dist <- buff_dist * (1 + y / st_area(st_buffer(x, buff_dist) ))
}
buffer_area <- st_area(st_buffer(x, buff_dist)) - st_area(x)
}
return(buff_dist)
}
buffer_distance(pl1, 100, 0.01)
#[1] 1.688372
st_area(st_buffer(pl1, buffer_distance(pl1, 100, 0.01))) - st_area(pl1)
# [1] 100.3634
plot(st_buffer(pl1, buffer_distance(pl1, 100, 0.01)))
plot(pl1, add = TRUE)