1

我对 R 上的st_bufferfrom packagesfbufferfrom package 的使用感到困惑。terra

我正在围绕点创建缓冲区,使用时sf::st_buffer我知道我需要在参数中使用缓冲区的半径dist,但是在使用时terra::buffer我需要在参数中指定缓冲区的直径width

这个对吗?

我在这里检查过sf::st_buffer,参数disthttps ://rdrr.io/r/stats/dist.html

在这里terra::buffer,参数widthhttps ://rdrr.io/cran/terra/man/width.html

4

3 回答 3

5

缓冲区是与对象的距离。在一般意义上,它既不是半径也不是直径。

当围绕一个点创建缓冲区时,缓冲区是一个圆,缓冲区距离(宽度)等于该圆的半径。

这不适用于线、多边形或栅格单元周围的缓冲区。

一些说明性代码terra

library(terra)
v <- vect(cbind(0,0), crs="+proj=utm +zone=1")
b <- buffer(v, 1)
ext(b)
#SpatExtent : -1, 1, -1, 1 (xmin, xmax, ymin, ymax)

v <- vect(cbind(0,0), crs="+proj=longlat")
# 1 degree at equator is ~ 111 km
b <- buffer(v, 111000)
round(ext(b), 2)
#SpatExtent : -1, 1, -1, 1 (xmin, xmax, ymin, ymax)

下面显示了不同纬度的经度/纬度点的缓冲区。这些缓冲区圆形,都具有相同的半径,尽管由于地球变平造成的扭曲很难看到。

v <- vect(cbind(0, seq(0, 80, 15)), crs="+proj=longlat")
b <- buffer(v, 1100000)
plot(b, asp=1, border=rainbow(8), lwd=2)
points(v)

在此处输入图像描述

于 2021-11-29T08:39:02.413 回答
3

我相信在理论上,正确的答案是@robert-hijmans 的答案(点周围的循环缓冲区只是通用缓冲区对象的特例)。

不过,我想指出另一个实际差异:对于未投影的坐标{sf},使用 Google 的 S2 库。S2 库的快捷方式和假设与 GEOS 有所不同,并产生了不同的缓冲区。

考虑这个例子,并注意红色缓冲区有多么不同(有点像像素化)。

library(nominatimlite)
library(sf)
library(terra)

a_point <- geo_lite_sf("Royal Observatory, Greenwich")

st_crs(a_point) # WGS84
# Coordinate Reference System:
#   User input: WGS 84 
#   wkt:
# GEOGCRS["WGS 84",
#     DATUM["World Geodetic System 1984",
#         ELLIPSOID["WGS 84",6378137,298.257223563,
#             LENGTHUNIT["metre",1]]],
#     PRIMEM["Greenwich",0,
#         ANGLEUNIT["degree",0.0174532925199433]],
#     CS[ellipsoidal,2],
#         AXIS["geodetic latitude (Lat)",north,
#             ORDER[1],
#             ANGLEUNIT["degree",0.0174532925199433]],
#         AXIS["geodetic longitude (Lon)",east,
#             ORDER[2],
#             ANGLEUNIT["degree",0.0174532925199433]],
#     ID["EPSG",4326]]

st_is_longlat(a_point) # this is important! S2 will be used.
# [1] TRUE


sf_buffer <- a_point |>
  st_buffer(dist = 500) |>
  st_geometry()

terra_buffer <- a_point |>
  vect() |>
  buffer(width = 500)

plot(sf_buffer, border = "red")
plot(terra_buffer, border = "blue", add = T)

红色和蓝色缓冲区

于 2021-11-29T09:44:36.507 回答
1

我不是terra(或多或少从未使用过它)的专家,但我认为这两个函数都需要缓冲区的半径:

# packages
library(sf)
#> Linking to GEOS 3.9.1, GDAL 3.2.1, PROJ 7.2.1
library(terra)
#> terra version 1.4.11

# data
point_sf <- st_as_sfc("POINT (0 0)", crs="+proj=merc")
point_terra <- vect("POINT (0 0)", crs="+proj=merc")

# buffer
buffer_sf <- st_buffer(point_sf, dist = 5)
buffer_terra <- buffer(point_terra, width = 5)

# plot
plot(buffer_sf, axes = TRUE, lwd = 10)
plot(buffer_terra, border = "red", add = TRUE, lwd = 3.5)

reprex 包于 2021-11-28 创建(v2.0.1)

于 2021-11-28T20:27:58.903 回答