Reputation: 55
I've been trying to figure it out how to create square buffers around points, but the closest I've came it's to generate a diamond shaped buffer using terra::buffer with quadsegs = 1. Reproducible code below. Any suggestions are much appreciated!
PS. Something went wrong when uploading the plot, but I believe it's a stackoverflow issue
library(terra)
library(geosphere)
lon <- seq(from = 10, by = 3/3600, length.out = 4)
lat <- rep(0, 4)
lon.lat <- cbind(lon, lat)
crs.lon.lat <- "epsg:4326"
grid <- terra::vect(lon.lat, crs = crs.lon.lat)
grid$id <- 1:length(grid)
res.7as <- geosphere::distGeo(c(0, 0), c(1, 0))*7/3600
grid.buf <- terra::buffer(grid,
width = res.7as,
quadsegs = 1)
plot(grid.buf)
plot(grid, add = T)
Upvotes: 2
Views: 2256
Reputation: 47146
You can use terra::spin
to rotate vector geometries.
Example data
library(terra)
lon <- seq(from = 10, by = 3/3600, length.out = 4)
lon.lat <- cbind(lon, 0)
pts <- terra::vect(lon.lat, crs = "epsg:4326")
buf <- buffer(pts, width=50, quadsegs = 1)
The center of rotation is vectorized, so you can do
xy <- crds(pts)
s <- spin(buf, 45, xy[,1], xy[,2])
plot(s); points(pts)
Upvotes: 2
Reputation: 2493
The following is an alternative solution purely based on sf
- st_buffer(..., endCapStyle = "SQUARE")
does the job for us.
library("sf")
example_point_1 = sf::st_point(c(0, 10))
example_point_2 = sf::st_point(c(110, 40))
example_points_sf <- sf::st_sfc(example_point_1, example_point_2) %>%
sf::st_sf()
sf::st_buffer(example_points_sf,
dist = 50,
endCapStyle = "SQUARE") %>% plot()
plot(example_points_sf, add = T)
Upvotes: 4
Reputation:
e.g. like this, starting from your data:
library(sf)
library(dplyr) ## for convenient dataframe manipulation
angle = pi/4 ## desired angle of rotation
## function to rotate a feature (of class sfc from package sf)
## around its centroid
rot = function(feature, a = 0){
cnt <- st_centroid(feature)
(feature - cnt) *
matrix(c(cos(a), sin(a), -sin(a), cos(a)), 2, 2) +
cnt
}
convert from class SpatVect
to class sfc
to apply {sf}
methods:
grid.buf.sf <- st_as_sf(grid.buf)
rotate as desired:
grid.buf.rotated <-
grid.buf.sf %>%
rowwise %>%
mutate(geometry = rot(geometry, angle))
re-convert to SpatVect
for use with {terra}
if desired:
grid.buf.rotated <- vect(grid.buf.rotated)
rotation function adopted from https://r-spatial.github.io/sf/articles/sf3.html#affine-transformations
Upvotes: 2